GMC V2 Add mute button to media notification.
This CL adds SetMute to MediaSession so that we can change mute status of the player from media session. Bug: 1238990 Change-Id: Ida26834d006cfb76056c72934d4844f44c0f0a3e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2881119 Commit-Queue: Jazz Xu <jazzhsu@chromium.org> Reviewed-by: Wez <wez@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Tommy Steimel <steimel@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Tao Wu <wutao@chromium.org> Reviewed-by: François Beaufort <beaufort.francois@gmail.com> Reviewed-by: Olga Sharonova <olka@chromium.org> Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Reviewed-by: Sean Topping <seantopping@chromium.org> Cr-Commit-Position: refs/heads/main@{#913135}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
c724a89f4b
commit
0f11c0f272
ash
chrome/browser/ui/global_media_controls
chromecast/browser
chromeos/services/assistant
components/media_message_center
content/browser
media
active_media_session_controller.ccmedia_web_contents_observer.cc
session
media_session_controller.ccmedia_session_controller.hmedia_session_controller_unittest.ccmedia_session_controllers_manager.ccmedia_session_controllers_manager.hmedia_session_impl.ccmedia_session_impl.hmedia_session_impl_service_routing_unittest.ccmedia_session_impl_uma_unittest.ccmedia_session_player_observer.hmedia_session_service_impl_browsertest.ccmedia_session_uma_helper.hmock_media_session_player_observer.ccmock_media_session_player_observer.hpepper_player_delegate.ccpepper_player_delegate.h
picture_in_picture
fuchsia/engine/browser
media/mojo/mojom
services/media_session
third_party/blink/renderer/core/html/media
@@ -134,6 +134,7 @@ const gfx::VectorIcon& GetVectorIconForMediaAction(MediaSessionAction action) {
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -90,6 +90,7 @@ const gfx::VectorIcon& GetVectorIconForMediaAction(MediaSessionAction action) {
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -68,6 +68,7 @@ void CastMediaSessionController::Send(
|
|||||||
case media_session::mojom::MediaSessionAction::kToggleCamera:
|
case media_session::mojom::MediaSessionAction::kToggleCamera:
|
||||||
case media_session::mojom::MediaSessionAction::kHangUp:
|
case media_session::mojom::MediaSessionAction::kHangUp:
|
||||||
case media_session::mojom::MediaSessionAction::kRaise:
|
case media_session::mojom::MediaSessionAction::kRaise:
|
||||||
|
case media_session::mojom::MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -71,8 +71,10 @@ void MediaSessionNotificationItem::MediaSessionInfoChanged(
|
|||||||
MaybeUnfreeze();
|
MaybeUnfreeze();
|
||||||
MaybeHideOrShowNotification();
|
MaybeHideOrShowNotification();
|
||||||
|
|
||||||
if (view_ && !frozen_)
|
if (view_ && !frozen_) {
|
||||||
view_->UpdateWithMediaSessionInfo(session_info_);
|
view_->UpdateWithMediaSessionInfo(session_info_);
|
||||||
|
view_->UpdateWithMuteStatus(session_info_->muted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaSessionNotificationItem::MediaSessionMetadataChanged(
|
void MediaSessionNotificationItem::MediaSessionMetadataChanged(
|
||||||
@@ -153,6 +155,7 @@ void MediaSessionNotificationItem::SetView(
|
|||||||
view_->UpdateWithMediaSessionInfo(session_info_);
|
view_->UpdateWithMediaSessionInfo(session_info_);
|
||||||
view_->UpdateWithMediaMetadata(session_metadata_);
|
view_->UpdateWithMediaMetadata(session_metadata_);
|
||||||
view_->UpdateWithMediaActions(session_actions_);
|
view_->UpdateWithMediaActions(session_actions_);
|
||||||
|
view_->UpdateWithMuteStatus(session_info_->muted);
|
||||||
|
|
||||||
if (session_position_.has_value())
|
if (session_position_.has_value())
|
||||||
view_->UpdateWithMediaPosition(*session_position_);
|
view_->UpdateWithMediaPosition(*session_position_);
|
||||||
@@ -196,6 +199,11 @@ void MediaSessionNotificationItem::Raise() {
|
|||||||
media_controller_remote_->Raise();
|
media_controller_remote_->Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionNotificationItem::SetMute(bool mute) {
|
||||||
|
if (!frozen_)
|
||||||
|
media_controller_remote_->SetMute(mute);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSessionNotificationItem::SetController(
|
void MediaSessionNotificationItem::SetController(
|
||||||
mojo::Remote<media_session::mojom::MediaController> controller,
|
mojo::Remote<media_session::mojom::MediaController> controller,
|
||||||
media_session::mojom::MediaSessionInfoPtr session_info) {
|
media_session::mojom::MediaSessionInfoPtr session_info) {
|
||||||
@@ -310,6 +318,7 @@ void MediaSessionNotificationItem::Unfreeze() {
|
|||||||
view_->UpdateWithMediaSessionInfo(session_info_);
|
view_->UpdateWithMediaSessionInfo(session_info_);
|
||||||
view_->UpdateWithMediaMetadata(session_metadata_);
|
view_->UpdateWithMediaMetadata(session_metadata_);
|
||||||
view_->UpdateWithMediaActions(session_actions_);
|
view_->UpdateWithMediaActions(session_actions_);
|
||||||
|
view_->UpdateWithMuteStatus(session_info_->muted);
|
||||||
|
|
||||||
if (session_position_.has_value())
|
if (session_position_.has_value())
|
||||||
view_->UpdateWithMediaPosition(*session_position_);
|
view_->UpdateWithMediaPosition(*session_position_);
|
||||||
|
@@ -92,7 +92,7 @@ class MediaSessionNotificationItem
|
|||||||
void Dismiss() override;
|
void Dismiss() override;
|
||||||
media_message_center::SourceType SourceType() override;
|
media_message_center::SourceType SourceType() override;
|
||||||
void SetVolume(float volume) override {}
|
void SetVolume(float volume) override {}
|
||||||
void SetMute(bool mute) override {}
|
void SetMute(bool mute) override;
|
||||||
|
|
||||||
// Calls |Raise()| on the underlying MediaSession, which will focus the
|
// Calls |Raise()| on the underlying MediaSession, which will focus the
|
||||||
// WebContents if the MediaSession is associated with one.
|
// WebContents if the MediaSession is associated with one.
|
||||||
|
@@ -61,6 +61,7 @@ class MockMediaSession : public content::MediaSession {
|
|||||||
MOCK_METHOD0(ToggleCamera, void());
|
MOCK_METHOD0(ToggleCamera, void());
|
||||||
MOCK_METHOD0(HangUp, void());
|
MOCK_METHOD0(HangUp, void());
|
||||||
MOCK_METHOD0(Raise, void());
|
MOCK_METHOD0(Raise, void());
|
||||||
|
MOCK_METHOD1(SetMute, void(bool));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(MockMediaSession);
|
DISALLOW_COPY_AND_ASSIGN(MockMediaSession);
|
||||||
|
@@ -100,6 +100,7 @@ class MediaControllerMock : public media_session::mojom::MediaController {
|
|||||||
MOCK_METHOD(void, ToggleCamera, ());
|
MOCK_METHOD(void, ToggleCamera, ());
|
||||||
MOCK_METHOD(void, HangUp, ());
|
MOCK_METHOD(void, HangUp, ());
|
||||||
MOCK_METHOD(void, Raise, ());
|
MOCK_METHOD(void, Raise, ());
|
||||||
|
MOCK_METHOD(void, SetMute, (bool mute));
|
||||||
void AddObserver(
|
void AddObserver(
|
||||||
mojo::PendingRemote<media_session::mojom::MediaControllerObserver> remote)
|
mojo::PendingRemote<media_session::mojom::MediaControllerObserver> remote)
|
||||||
override {
|
override {
|
||||||
|
@@ -58,6 +58,7 @@ class COMPONENT_EXPORT(ASSISTANT_SERVICE) AssistantMediaSession
|
|||||||
void ToggleCamera() override {}
|
void ToggleCamera() override {}
|
||||||
void HangUp() override {}
|
void HangUp() override {}
|
||||||
void Raise() override {}
|
void Raise() override {}
|
||||||
|
void SetMute(bool mute) override {}
|
||||||
|
|
||||||
// Requests/abandons audio focus to the AudioFocusManager.
|
// Requests/abandons audio focus to the AudioFocusManager.
|
||||||
void RequestAudioFocus(media_session::mojom::AudioFocusType audio_focus_type);
|
void RequestAudioFocus(media_session::mojom::AudioFocusType audio_focus_type);
|
||||||
|
@@ -104,6 +104,7 @@ const gfx::VectorIcon* GetVectorIconForMediaAction(MediaSessionAction action) {
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -111,6 +111,7 @@ const gfx::VectorIcon* GetVectorIconForMediaAction(MediaSessionAction action) {
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -154,6 +155,7 @@ const std::u16string GetAccessibleNameForMediaAction(
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -439,20 +441,19 @@ MediaNotificationViewModernImpl::MediaNotificationViewModernImpl(
|
|||||||
volume_slider->SetPreferredSize(kVolumeSliderSize);
|
volume_slider->SetPreferredSize(kVolumeSliderSize);
|
||||||
volume_slider_ =
|
volume_slider_ =
|
||||||
util_buttons_container->AddChildView(std::move(volume_slider));
|
util_buttons_container->AddChildView(std::move(volume_slider));
|
||||||
|
|
||||||
auto mute_button =
|
|
||||||
std::make_unique<views::ToggleImageButton>(base::BindRepeating(
|
|
||||||
&MediaNotificationViewModernImpl::OnMuteButtonClicked,
|
|
||||||
base::Unretained(this)));
|
|
||||||
mute_button->SetPreferredSize(kMuteButtonSize);
|
|
||||||
mute_button->SetImageHorizontalAlignment(
|
|
||||||
views::ImageButton::HorizontalAlignment::ALIGN_CENTER);
|
|
||||||
mute_button->SetImageVerticalAlignment(
|
|
||||||
views::ImageButton::VerticalAlignment::ALIGN_MIDDLE);
|
|
||||||
mute_button_ =
|
|
||||||
util_buttons_container->AddChildView(std::move(mute_button));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto mute_button =
|
||||||
|
std::make_unique<views::ToggleImageButton>(base::BindRepeating(
|
||||||
|
&MediaNotificationViewModernImpl::OnMuteButtonClicked,
|
||||||
|
base::Unretained(this)));
|
||||||
|
mute_button->SetPreferredSize(kMuteButtonSize);
|
||||||
|
mute_button->SetImageHorizontalAlignment(
|
||||||
|
views::ImageButton::HorizontalAlignment::ALIGN_CENTER);
|
||||||
|
mute_button->SetImageVerticalAlignment(
|
||||||
|
views::ImageButton::VerticalAlignment::ALIGN_MIDDLE);
|
||||||
|
mute_button_ = util_buttons_container->AddChildView(std::move(mute_button));
|
||||||
|
|
||||||
AddChildView(std::move(util_buttons_container));
|
AddChildView(std::move(util_buttons_container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -199,6 +199,7 @@ void ActiveMediaSessionController::PerformAction(MediaSessionAction action) {
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -251,6 +252,7 @@ ActiveMediaSessionController::MediaSessionActionToKeyCode(
|
|||||||
case MediaSessionAction::kToggleCamera:
|
case MediaSessionAction::kToggleCamera:
|
||||||
case MediaSessionAction::kHangUp:
|
case MediaSessionAction::kHangUp:
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -337,6 +337,9 @@ void MediaWebContentsObserver::MediaPlayerObserverHostImpl::
|
|||||||
media_web_contents_observer_->web_contents_impl()->MediaMutedStatusChanged(
|
media_web_contents_observer_->web_contents_impl()->MediaMutedStatusChanged(
|
||||||
media_player_id_, muted);
|
media_player_id_, muted);
|
||||||
|
|
||||||
|
media_web_contents_observer_->session_controllers_manager()
|
||||||
|
->OnMediaMutedStatusChanged(media_player_id_, muted);
|
||||||
|
|
||||||
PlayerInfo* player_info = GetPlayerInfo();
|
PlayerInfo* player_info = GetPlayerInfo();
|
||||||
if (!player_info)
|
if (!player_info)
|
||||||
return;
|
return;
|
||||||
|
@@ -141,6 +141,14 @@ void MediaSessionController::OnSetAudioSinkId(
|
|||||||
->SetAudioSinkId(hashed_sink_id);
|
->SetAudioSinkId(hashed_sink_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionController::OnSetMute(int player_id, bool mute) {
|
||||||
|
DCHECK_EQ(player_id_, player_id);
|
||||||
|
|
||||||
|
web_contents_->media_web_contents_observer()
|
||||||
|
->GetMediaPlayerRemote(id_)
|
||||||
|
->RequestMute(mute);
|
||||||
|
}
|
||||||
|
|
||||||
RenderFrameHost* MediaSessionController::render_frame_host() const {
|
RenderFrameHost* MediaSessionController::render_frame_host() const {
|
||||||
return RenderFrameHost::FromID(id_.frame_routing_id);
|
return RenderFrameHost::FromID(id_.frame_routing_id);
|
||||||
}
|
}
|
||||||
@@ -185,6 +193,10 @@ void MediaSessionController::OnMediaPositionStateChanged(
|
|||||||
media_session_->RebuildAndNotifyMediaPositionChanged();
|
media_session_->RebuildAndNotifyMediaPositionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionController::OnMediaMutedStatusChanged(bool mute) {
|
||||||
|
media_session_->OnMediaMutedStatusChanged(mute);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSessionController::OnPictureInPictureAvailabilityChanged(
|
void MediaSessionController::OnPictureInPictureAvailabilityChanged(
|
||||||
bool available) {
|
bool available) {
|
||||||
is_picture_in_picture_available_ = available;
|
is_picture_in_picture_available_ = available;
|
||||||
|
@@ -60,6 +60,7 @@ class CONTENT_EXPORT MediaSessionController
|
|||||||
void OnExitPictureInPicture(int player_id) override;
|
void OnExitPictureInPicture(int player_id) override;
|
||||||
void OnSetAudioSinkId(int player_id,
|
void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) override;
|
const std::string& raw_device_id) override;
|
||||||
|
void OnSetMute(int player_id, bool mute) override;
|
||||||
RenderFrameHost* render_frame_host() const override;
|
RenderFrameHost* render_frame_host() const override;
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override;
|
int player_id) const override;
|
||||||
@@ -82,6 +83,8 @@ class CONTENT_EXPORT MediaSessionController
|
|||||||
void OnMediaPositionStateChanged(
|
void OnMediaPositionStateChanged(
|
||||||
const media_session::MediaPosition& position);
|
const media_session::MediaPosition& position);
|
||||||
|
|
||||||
|
void OnMediaMutedStatusChanged(bool mute);
|
||||||
|
|
||||||
// Called when the media picture-in-picture availability has changed.
|
// Called when the media picture-in-picture availability has changed.
|
||||||
void OnPictureInPictureAvailabilityChanged(bool available);
|
void OnPictureInPictureAvailabilityChanged(bool available);
|
||||||
|
|
||||||
|
@@ -138,6 +138,8 @@ class TestMediaPlayer : public media::mojom::MediaPlayer {
|
|||||||
|
|
||||||
void RequestExitPictureInPicture() override {}
|
void RequestExitPictureInPicture() override {}
|
||||||
|
|
||||||
|
void RequestMute(bool mute) override {}
|
||||||
|
|
||||||
void SetVolumeMultiplier(double multiplier) override {
|
void SetVolumeMultiplier(double multiplier) override {
|
||||||
received_volume_multiplier_ = multiplier;
|
received_volume_multiplier_ = multiplier;
|
||||||
if (run_loop_for_volume_)
|
if (run_loop_for_volume_)
|
||||||
|
@@ -104,6 +104,16 @@ void MediaSessionControllersManager::WebContentsMutedStateChanged(bool muted) {
|
|||||||
entry.second->WebContentsMutedStateChanged(muted);
|
entry.second->WebContentsMutedStateChanged(muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionControllersManager::OnMediaMutedStatusChanged(
|
||||||
|
const MediaPlayerId& id,
|
||||||
|
bool mute) {
|
||||||
|
if (!IsMediaSessionEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
MediaSessionController* const controller = FindOrCreateController(id);
|
||||||
|
controller->OnMediaMutedStatusChanged(mute);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSessionControllersManager::OnPictureInPictureAvailabilityChanged(
|
void MediaSessionControllersManager::OnPictureInPictureAvailabilityChanged(
|
||||||
const MediaPlayerId& id,
|
const MediaPlayerId& id,
|
||||||
bool available) {
|
bool available) {
|
||||||
|
@@ -67,6 +67,9 @@ class CONTENT_EXPORT MediaSessionControllersManager {
|
|||||||
// Called when the WebContents was muted or unmuted.
|
// Called when the WebContents was muted or unmuted.
|
||||||
void WebContentsMutedStateChanged(bool muted);
|
void WebContentsMutedStateChanged(bool muted);
|
||||||
|
|
||||||
|
// Called when the player's mute status changed.
|
||||||
|
void OnMediaMutedStatusChanged(const MediaPlayerId& id, bool mute);
|
||||||
|
|
||||||
// Called when picture-in-picture availability for the player |id| has
|
// Called when picture-in-picture availability for the player |id| has
|
||||||
// changed.
|
// changed.
|
||||||
void OnPictureInPictureAvailabilityChanged(const MediaPlayerId& id,
|
void OnPictureInPictureAvailabilityChanged(const MediaPlayerId& id,
|
||||||
|
@@ -149,6 +149,8 @@ MediaSessionUserAction MediaSessionActionToUserAction(
|
|||||||
return MediaSessionUserAction::kHangUp;
|
return MediaSessionUserAction::kHangUp;
|
||||||
case media_session::mojom::MediaSessionAction::kRaise:
|
case media_session::mojom::MediaSessionAction::kRaise:
|
||||||
return MediaSessionUserAction::kRaise;
|
return MediaSessionUserAction::kRaise;
|
||||||
|
case media_session::mojom::MediaSessionAction::kSetMute:
|
||||||
|
return MediaSessionUserAction::kSetMute;
|
||||||
}
|
}
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
return MediaSessionUserAction::kPlay;
|
return MediaSessionUserAction::kPlay;
|
||||||
@@ -1013,6 +1015,8 @@ MediaSessionImpl::GetMediaSessionInfoSync() {
|
|||||||
info->camera_state = media_session::mojom::CameraState::kUnknown;
|
info->camera_state = media_session::mojom::CameraState::kUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info->muted = is_muted_;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,6 +1177,12 @@ void MediaSessionImpl::Raise() {
|
|||||||
delegate->ActivateContents(web_contents());
|
delegate->ActivateContents(web_contents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionImpl::SetMute(bool mute) {
|
||||||
|
DCHECK_EQ(normal_players_.size(), 1u);
|
||||||
|
normal_players_.begin()->first.observer->OnSetMute(
|
||||||
|
normal_players_.begin()->first.player_id, mute);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSessionImpl::GetMediaImageBitmap(
|
void MediaSessionImpl::GetMediaImageBitmap(
|
||||||
const media_session::MediaImage& image,
|
const media_session::MediaImage& image,
|
||||||
int minimum_size_px,
|
int minimum_size_px,
|
||||||
@@ -1481,6 +1491,11 @@ MediaSessionServiceImpl* MediaSessionImpl::ComputeServiceForRouting() {
|
|||||||
return best_frame ? services_[best_frame->GetGlobalId()] : nullptr;
|
return best_frame ? services_[best_frame->GetGlobalId()] : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSessionImpl::OnMediaMutedStatusChanged(bool mute) {
|
||||||
|
is_muted_ = mute;
|
||||||
|
RebuildAndNotifyMediaSessionInfoChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSessionImpl::OnPictureInPictureAvailabilityChanged() {
|
void MediaSessionImpl::OnPictureInPictureAvailabilityChanged() {
|
||||||
if (normal_players_.size() != 1)
|
if (normal_players_.size() != 1)
|
||||||
return;
|
return;
|
||||||
|
@@ -279,6 +279,9 @@ class MediaSessionImpl : public MediaSession,
|
|||||||
// Brings the associated tab into focus.
|
// Brings the associated tab into focus.
|
||||||
void Raise() override;
|
void Raise() override;
|
||||||
|
|
||||||
|
// Mute or unmute the media player.
|
||||||
|
void SetMute(bool mute) override;
|
||||||
|
|
||||||
// Downloads the bitmap version of a MediaImage at least |minimum_size_px|
|
// Downloads the bitmap version of a MediaImage at least |minimum_size_px|
|
||||||
// and closest to |desired_size_px|. If the download failed, was too small or
|
// and closest to |desired_size_px|. If the download failed, was too small or
|
||||||
// the image did not come from the media session then returns a null image.
|
// the image did not come from the media session then returns a null image.
|
||||||
@@ -292,6 +295,8 @@ class MediaSessionImpl : public MediaSession,
|
|||||||
return audio_focus_group_id_;
|
return audio_focus_group_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnMediaMutedStatusChanged(bool mute);
|
||||||
|
|
||||||
void OnPictureInPictureAvailabilityChanged();
|
void OnPictureInPictureAvailabilityChanged();
|
||||||
|
|
||||||
// Called when any of the normal players have switched to a different audio
|
// Called when any of the normal players have switched to a different audio
|
||||||
@@ -481,6 +486,8 @@ class MediaSessionImpl : public MediaSession,
|
|||||||
// True if the WebContents associated with this MediaSessionImpl is focused.
|
// True if the WebContents associated with this MediaSessionImpl is focused.
|
||||||
bool focused_ = false;
|
bool focused_ = false;
|
||||||
|
|
||||||
|
bool is_muted_ = false;
|
||||||
|
|
||||||
// Used to persist audio device selection between navigations on the same
|
// Used to persist audio device selection between navigations on the same
|
||||||
// origin.
|
// origin.
|
||||||
url::Origin origin_;
|
url::Origin origin_;
|
||||||
|
@@ -58,6 +58,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
|
|||||||
MOCK_METHOD1(OnExitPictureInPicture, void(int player_id));
|
MOCK_METHOD1(OnExitPictureInPicture, void(int player_id));
|
||||||
MOCK_METHOD2(OnSetAudioSinkId,
|
MOCK_METHOD2(OnSetAudioSinkId,
|
||||||
void(int player_id, const std::string& raw_device_id));
|
void(int player_id, const std::string& raw_device_id));
|
||||||
|
MOCK_METHOD2(OnSetMute, void(int player_id, bool mute));
|
||||||
|
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override {
|
int player_id) const override {
|
||||||
|
@@ -44,6 +44,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
|
|||||||
void OnExitPictureInPicture(int player_id) override {}
|
void OnExitPictureInPicture(int player_id) override {}
|
||||||
void OnSetAudioSinkId(int player_id,
|
void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) override {}
|
const std::string& raw_device_id) override {}
|
||||||
|
void OnSetMute(int player_id, bool mute) override {}
|
||||||
|
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override {
|
int player_id) const override {
|
||||||
|
@@ -52,6 +52,9 @@ class MediaSessionPlayerObserver {
|
|||||||
virtual void OnSetAudioSinkId(int player_id,
|
virtual void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) = 0;
|
const std::string& raw_device_id) = 0;
|
||||||
|
|
||||||
|
// The given |player_id| has been requested to mute or unmute.
|
||||||
|
virtual void OnSetMute(int player_id, bool mute) = 0;
|
||||||
|
|
||||||
// Returns the position for |player_id|.
|
// Returns the position for |player_id|.
|
||||||
virtual absl::optional<media_session::MediaPosition> GetPosition(
|
virtual absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const = 0;
|
int player_id) const = 0;
|
||||||
|
@@ -61,6 +61,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
|
|||||||
void OnExitPictureInPicture(int player_id) override {}
|
void OnExitPictureInPicture(int player_id) override {}
|
||||||
void OnSetAudioSinkId(int player_id,
|
void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) override {}
|
const std::string& raw_device_id) override {}
|
||||||
|
void OnSetMute(int player_id, bool mute) override {}
|
||||||
|
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override {
|
int player_id) const override {
|
||||||
|
@@ -50,7 +50,8 @@ class CONTENT_EXPORT MediaSessionUmaHelper {
|
|||||||
kToggleCamera = 17,
|
kToggleCamera = 17,
|
||||||
kHangUp = 18,
|
kHangUp = 18,
|
||||||
kRaise = 19,
|
kRaise = 19,
|
||||||
kMaxValue = kRaise,
|
kSetMute = 20,
|
||||||
|
kMaxValue = kSetMute,
|
||||||
};
|
};
|
||||||
|
|
||||||
MediaSessionUmaHelper();
|
MediaSessionUmaHelper();
|
||||||
|
@@ -89,6 +89,11 @@ void MockMediaSessionPlayerObserver::OnSetAudioSinkId(
|
|||||||
players_[player_id].audio_sink_id_ = raw_device_id;
|
players_[player_id].audio_sink_id_ = raw_device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MockMediaSessionPlayerObserver::OnSetMute(int player_id, bool mute) {
|
||||||
|
EXPECT_GE(player_id, 0);
|
||||||
|
EXPECT_GT(players_.size(), static_cast<size_t>(player_id));
|
||||||
|
}
|
||||||
|
|
||||||
absl::optional<media_session::MediaPosition>
|
absl::optional<media_session::MediaPosition>
|
||||||
MockMediaSessionPlayerObserver::GetPosition(int player_id) const {
|
MockMediaSessionPlayerObserver::GetPosition(int player_id) const {
|
||||||
EXPECT_GE(player_id, 0);
|
EXPECT_GE(player_id, 0);
|
||||||
|
@@ -34,6 +34,7 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
|
|||||||
void OnExitPictureInPicture(int player_id) override;
|
void OnExitPictureInPicture(int player_id) override;
|
||||||
void OnSetAudioSinkId(int player_id,
|
void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) override;
|
const std::string& raw_device_id) override;
|
||||||
|
void OnSetMute(int player_id, bool mute) override;
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override;
|
int player_id) const override;
|
||||||
bool IsPictureInPictureAvailable(int player_id) const override;
|
bool IsPictureInPictureAvailable(int player_id) const override;
|
||||||
|
@@ -80,6 +80,8 @@ void PepperPlayerDelegate::OnSetAudioSinkId(int player_id,
|
|||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PepperPlayerDelegate::OnSetMute(int player_id, bool mute) {}
|
||||||
|
|
||||||
absl::optional<media_session::MediaPosition> PepperPlayerDelegate::GetPosition(
|
absl::optional<media_session::MediaPosition> PepperPlayerDelegate::GetPosition(
|
||||||
int player_id) const {
|
int player_id) const {
|
||||||
// Pepper does not support position data.
|
// Pepper does not support position data.
|
||||||
|
@@ -34,6 +34,7 @@ class PepperPlayerDelegate : public MediaSessionPlayerObserver {
|
|||||||
void OnExitPictureInPicture(int player_id) override;
|
void OnExitPictureInPicture(int player_id) override;
|
||||||
void OnSetAudioSinkId(int player_id,
|
void OnSetAudioSinkId(int player_id,
|
||||||
const std::string& raw_device_id) override;
|
const std::string& raw_device_id) override;
|
||||||
|
void OnSetMute(int player_id, bool mute) override;
|
||||||
absl::optional<media_session::MediaPosition> GetPosition(
|
absl::optional<media_session::MediaPosition> GetPosition(
|
||||||
int player_id) const override;
|
int player_id) const override;
|
||||||
bool IsPictureInPictureAvailable(int player_id) const override;
|
bool IsPictureInPictureAvailable(int player_id) const override;
|
||||||
|
@@ -130,6 +130,7 @@ class PictureInPictureMediaPlayerReceiver : public media::mojom::MediaPlayer {
|
|||||||
void RequestSeekTo(base::TimeDelta seek_time) override {}
|
void RequestSeekTo(base::TimeDelta seek_time) override {}
|
||||||
void RequestEnterPictureInPicture() override {}
|
void RequestEnterPictureInPicture() override {}
|
||||||
void RequestExitPictureInPicture() override {}
|
void RequestExitPictureInPicture() override {}
|
||||||
|
void RequestMute(bool mute) override {}
|
||||||
void SetVolumeMultiplier(double multiplier) override {}
|
void SetVolumeMultiplier(double multiplier) override {}
|
||||||
void SetPersistentState(bool persistent) override {}
|
void SetPersistentState(bool persistent) override {}
|
||||||
void SetPowerExperimentState(bool enabled) override {}
|
void SetPowerExperimentState(bool enabled) override {}
|
||||||
|
@@ -55,6 +55,8 @@ fuchsia::media::sessions2::PlayerCapabilityFlags ActionToCapabilityFlag(
|
|||||||
return {}; // PlayerControl does not support hanging up.
|
return {}; // PlayerControl does not support hanging up.
|
||||||
case MediaSessionAction::kRaise:
|
case MediaSessionAction::kRaise:
|
||||||
return {}; // PlayerControl does not support raising.
|
return {}; // PlayerControl does not support raising.
|
||||||
|
case MediaSessionAction::kSetMute:
|
||||||
|
return {}; // TODO(crbug.com/1240811): implement set mute.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@ class FakeMediaSession : public content::MediaSession {
|
|||||||
MOCK_METHOD0(ToggleCamera, void());
|
MOCK_METHOD0(ToggleCamera, void());
|
||||||
MOCK_METHOD0(HangUp, void());
|
MOCK_METHOD0(HangUp, void());
|
||||||
MOCK_METHOD0(Raise, void());
|
MOCK_METHOD0(Raise, void());
|
||||||
|
MOCK_METHOD1(SetMute, void(bool));
|
||||||
|
|
||||||
// content::MediaSession APIs faked to implement testing behaviour.
|
// content::MediaSession APIs faked to implement testing behaviour.
|
||||||
MOCK_METHOD1(DidReceiveAction,
|
MOCK_METHOD1(DidReceiveAction,
|
||||||
|
@@ -9,7 +9,8 @@ import "mojo/public/mojom/base/time.mojom";
|
|||||||
import "services/media_session/public/mojom/media_session.mojom";
|
import "services/media_session/public/mojom/media_session.mojom";
|
||||||
import "ui/gfx/geometry/mojom/geometry.mojom";
|
import "ui/gfx/geometry/mojom/geometry.mojom";
|
||||||
|
|
||||||
// Implemented by HTMLMediaElement in the renderer process.
|
// Implemented by HTMLMediaElement in the renderer process to allow the
|
||||||
|
// browser to control media playback.
|
||||||
interface MediaPlayer {
|
interface MediaPlayer {
|
||||||
// Requests the media player to start or resume media playback.
|
// Requests the media player to start or resume media playback.
|
||||||
RequestPlay();
|
RequestPlay();
|
||||||
@@ -32,6 +33,9 @@ interface MediaPlayer {
|
|||||||
// Requests the media player to exit the Picture-in-Picture mode.
|
// Requests the media player to exit the Picture-in-Picture mode.
|
||||||
RequestExitPictureInPicture();
|
RequestExitPictureInPicture();
|
||||||
|
|
||||||
|
// Requests the media player to mute or unmute.
|
||||||
|
RequestMute(bool mute);
|
||||||
|
|
||||||
// Set the volume multiplier to control audio ducking.
|
// Set the volume multiplier to control audio ducking.
|
||||||
// Output volume should be set to |player_volume| * |multiplier|. The range
|
// Output volume should be set to |player_volume| * |multiplier|. The range
|
||||||
// of |multiplier| is [0, 1], where 1 indicates normal (non-ducked) playback.
|
// of |multiplier| is [0, 1], where 1 indicates normal (non-ducked) playback.
|
||||||
|
@@ -328,6 +328,13 @@ void MediaController::Raise() {
|
|||||||
session_->ipc()->Raise();
|
session_->ipc()->Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaController::SetMute(bool mute) {
|
||||||
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
|
||||||
|
if (session_)
|
||||||
|
session_->ipc()->SetMute(mute);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaController::SetMediaSession(AudioFocusRequest* session) {
|
void MediaController::SetMediaSession(AudioFocusRequest* session) {
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
|
||||||
|
@@ -57,6 +57,7 @@ class MediaController : public mojom::MediaController,
|
|||||||
void ToggleCamera() override;
|
void ToggleCamera() override;
|
||||||
void HangUp() override;
|
void HangUp() override;
|
||||||
void Raise() override;
|
void Raise() override;
|
||||||
|
void SetMute(bool mute) override;
|
||||||
|
|
||||||
// mojom::MediaSessionObserver overrides.
|
// mojom::MediaSessionObserver overrides.
|
||||||
void MediaSessionInfoChanged(
|
void MediaSessionInfoChanged(
|
||||||
|
@@ -168,6 +168,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
|
|||||||
void ToggleCamera() override {}
|
void ToggleCamera() override {}
|
||||||
void HangUp() override {}
|
void HangUp() override {}
|
||||||
void Raise() override {}
|
void Raise() override {}
|
||||||
|
void SetMute(bool mute) override {}
|
||||||
|
|
||||||
void SetIsControllable(bool value);
|
void SetIsControllable(bool value);
|
||||||
void SetPreferStop(bool value) { prefer_stop_ = value; }
|
void SetPreferStop(bool value) { prefer_stop_ = value; }
|
||||||
|
@@ -160,6 +160,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) TestMediaController
|
|||||||
void ToggleCamera() override {}
|
void ToggleCamera() override {}
|
||||||
void HangUp() override {}
|
void HangUp() override {}
|
||||||
void Raise() override {}
|
void Raise() override {}
|
||||||
|
void SetMute(bool mute) override {}
|
||||||
|
|
||||||
int toggle_suspend_resume_count() const {
|
int toggle_suspend_resume_count() const {
|
||||||
return toggle_suspend_resume_count_;
|
return toggle_suspend_resume_count_;
|
||||||
|
@@ -58,6 +58,7 @@ void PerformMediaSessionAction(
|
|||||||
case mojom::MediaSessionAction::kRaise:
|
case mojom::MediaSessionAction::kRaise:
|
||||||
media_controller_remote->Raise();
|
media_controller_remote->Raise();
|
||||||
break;
|
break;
|
||||||
|
case mojom::MediaSessionAction::kSetMute:
|
||||||
case mojom::MediaSessionAction::kSkipAd:
|
case mojom::MediaSessionAction::kSkipAd:
|
||||||
case mojom::MediaSessionAction::kSeekTo:
|
case mojom::MediaSessionAction::kSeekTo:
|
||||||
case mojom::MediaSessionAction::kScrubTo:
|
case mojom::MediaSessionAction::kScrubTo:
|
||||||
|
@@ -33,7 +33,7 @@ interface MediaControllerManager {
|
|||||||
// session, otherwise media sessions will be associated with a particular media
|
// session, otherwise media sessions will be associated with a particular media
|
||||||
// session provided to the service when creating the media controller. If the
|
// session provided to the service when creating the media controller. If the
|
||||||
// media session is not controllable then the commands will be no-ops.
|
// media session is not controllable then the commands will be no-ops.
|
||||||
// Next Method ID: 18
|
// Next Method ID: 19
|
||||||
[Stable]
|
[Stable]
|
||||||
interface MediaController {
|
interface MediaController {
|
||||||
// Suspend the media session.
|
// Suspend the media session.
|
||||||
@@ -109,6 +109,9 @@ interface MediaController {
|
|||||||
// Display the source of the MediaSession (e.g. show the tab or the
|
// Display the source of the MediaSession (e.g. show the tab or the
|
||||||
// application).
|
// application).
|
||||||
[MinVersion=2] Raise@17();
|
[MinVersion=2] Raise@17();
|
||||||
|
|
||||||
|
// Mute or unmute the media player.
|
||||||
|
[MinVersion=3] SetMute@18(bool mute);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The observer for observing media controller events. This is different to a
|
// The observer for observing media controller events. This is different to a
|
||||||
|
@@ -36,6 +36,7 @@ enum MediaSessionAction {
|
|||||||
[MinVersion=11] kToggleCamera,
|
[MinVersion=11] kToggleCamera,
|
||||||
[MinVersion=11] kHangUp,
|
[MinVersion=11] kHangUp,
|
||||||
[MinVersion=12] kRaise,
|
[MinVersion=12] kRaise,
|
||||||
|
[MinVersion=13] kSetMute,
|
||||||
};
|
};
|
||||||
|
|
||||||
[Stable, Extensible]
|
[Stable, Extensible]
|
||||||
@@ -189,6 +190,9 @@ struct MediaSessionInfo {
|
|||||||
|
|
||||||
// Tracks whether the camera is turned on in WebRTC sessions.
|
// Tracks whether the camera is turned on in WebRTC sessions.
|
||||||
[MinVersion=11] CameraState camera_state;
|
[MinVersion=11] CameraState camera_state;
|
||||||
|
|
||||||
|
// Tracks whether the media player is muted.
|
||||||
|
[MinVersion=12] bool muted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Contains debugging information about a MediaSession. This will be displayed
|
// Contains debugging information about a MediaSession. This will be displayed
|
||||||
@@ -331,4 +335,7 @@ interface MediaSession {
|
|||||||
// Display the source of the MediaSession (e.g. show the tab or the
|
// Display the source of the MediaSession (e.g. show the tab or the
|
||||||
// application).
|
// application).
|
||||||
[MinVersion=12] Raise@21();
|
[MinVersion=12] Raise@21();
|
||||||
|
|
||||||
|
// Mute or unmute the media player.
|
||||||
|
[MinVersion=13] SetMute@22(bool mute);
|
||||||
};
|
};
|
||||||
|
@@ -4644,6 +4644,10 @@ void HTMLMediaElement::RequestSeekTo(base::TimeDelta seek_time) {
|
|||||||
setCurrentTime(seek_time.InSecondsF());
|
setCurrentTime(seek_time.InSecondsF());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTMLMediaElement::RequestMute(bool mute) {
|
||||||
|
setMuted(mute);
|
||||||
|
}
|
||||||
|
|
||||||
void HTMLMediaElement::SetVolumeMultiplier(double multiplier) {
|
void HTMLMediaElement::SetVolumeMultiplier(double multiplier) {
|
||||||
if (web_media_player_)
|
if (web_media_player_)
|
||||||
web_media_player_->SetVolumeMultiplier(multiplier);
|
web_media_player_->SetVolumeMultiplier(multiplier);
|
||||||
|
@@ -518,6 +518,7 @@ class CORE_EXPORT HTMLMediaElement
|
|||||||
void RequestSeekTo(base::TimeDelta seek_time) override;
|
void RequestSeekTo(base::TimeDelta seek_time) override;
|
||||||
void RequestEnterPictureInPicture() override {}
|
void RequestEnterPictureInPicture() override {}
|
||||||
void RequestExitPictureInPicture() override {}
|
void RequestExitPictureInPicture() override {}
|
||||||
|
void RequestMute(bool mute) override;
|
||||||
void SetVolumeMultiplier(double multiplier) override;
|
void SetVolumeMultiplier(double multiplier) override;
|
||||||
void SetPersistentState(bool persistent) override {}
|
void SetPersistentState(bool persistent) override {}
|
||||||
void SetPowerExperimentState(bool enabled) override;
|
void SetPowerExperimentState(bool enabled) override;
|
||||||
|
Reference in New Issue
Block a user