Commit e5b869b7 authored by Noah Rose Ledesma's avatar Noah Rose Ledesma Committed by Commit Bot

Reland "GMC: Add IPC for switching the audio output device"

This is a reland of f300ac05

The original change added a method to a mojom interface but neglected to
implemnet this method for a class in ChromeOS. This reland adds the
missing implementation that caused builds to fail.

Original change's description:
> GMC: Add IPC for switching the audio output device
>
> This change adds methods used by the global media controls ui for
> switching the audio output device used by a page.
>
> MediaController::SetAudioSinkId was created allowing the
> MediaNotificationService to route the audio output of a
> MediaNotificationSession to a specified audio device.
>
> Mojo interfaces were expanded to allow for this IPC between the
> controller and session.
>
> Bug: 1096243
> Change-Id: Icd0ad17d6ef88ec297444b8b2cbc7ddda6c2c4c9
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2295799
> Commit-Queue: Noah Rose Ledesma <noahrose@google.com>
> Reviewed-by: Sergey Ulanov <sergeyu@chromium.org>
> Reviewed-by: Sean Topping <seantopping@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Becca Hughes <beccahughes@chromium.org>
> Reviewed-by: Tommy Steimel <steimel@chromium.org>
> Auto-Submit: Noah Rose Ledesma <noahrose@google.com>
> Cr-Commit-Position: refs/heads/master@{#792935}

Bug: 1096243
Change-Id: I0dad44fc7d1c8daac50519e8625a3cc2150fa34c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2328034Reviewed-by: default avatarSean Topping <seantopping@chromium.org>
Reviewed-by: default avatarYue Li <updowndota@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarBecca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Noah Rose Ledesma <noahrose@google.com>
Cr-Commit-Position: refs/heads/master@{#794619}
parent e2c08269
...@@ -221,7 +221,9 @@ bool MediaNotificationService::Session::IsPlaying() { ...@@ -221,7 +221,9 @@ bool MediaNotificationService::Session::IsPlaying() {
return is_playing_; return is_playing_;
} }
void MediaNotificationService::Session::SetAudioSinkId(const std::string& id) {} void MediaNotificationService::Session::SetAudioSinkId(const std::string& id) {
controller_->SetAudioSinkId(id);
}
// static // static
void MediaNotificationService::Session::RecordDismissReason( void MediaNotificationService::Session::RecordDismissReason(
......
...@@ -56,6 +56,7 @@ class MockMediaSession : public content::MediaSession { ...@@ -56,6 +56,7 @@ class MockMediaSession : public content::MediaSession {
MOCK_METHOD1(ScrubTo, void(base::TimeDelta)); MOCK_METHOD1(ScrubTo, void(base::TimeDelta));
MOCK_METHOD0(EnterPictureInPicture, void()); MOCK_METHOD0(EnterPictureInPicture, void());
MOCK_METHOD0(ExitPictureInPicture, void()); MOCK_METHOD0(ExitPictureInPicture, void());
MOCK_METHOD1(SetAudioSinkId, void(const base::Optional<std::string>& id));
private: private:
DISALLOW_COPY_AND_ASSIGN(MockMediaSession); DISALLOW_COPY_AND_ASSIGN(MockMediaSession);
...@@ -105,7 +106,6 @@ class CastMediaBlockerTest : public content::RenderViewHostTestHarness { ...@@ -105,7 +106,6 @@ class CastMediaBlockerTest : public content::RenderViewHostTestHarness {
DISALLOW_COPY_AND_ASSIGN(CastMediaBlockerTest); DISALLOW_COPY_AND_ASSIGN(CastMediaBlockerTest);
}; };
TEST_F(CastMediaBlockerTest, Block_Unblock_Suspended) { TEST_F(CastMediaBlockerTest, Block_Unblock_Suspended) {
// Testing block/unblock operations do nothing if media never plays. // Testing block/unblock operations do nothing if media never plays.
EXPECT_CALL(*media_session_, Suspend(_)).Times(0); EXPECT_CALL(*media_session_, Suspend(_)).Times(0);
......
...@@ -59,6 +59,7 @@ class COMPONENT_EXPORT(ASSISTANT_SERVICE) AssistantMediaSession ...@@ -59,6 +59,7 @@ class COMPONENT_EXPORT(ASSISTANT_SERVICE) AssistantMediaSession
void ScrubTo(base::TimeDelta seek_time) override {} void ScrubTo(base::TimeDelta seek_time) override {}
void EnterPictureInPicture() override {} void EnterPictureInPicture() override {}
void ExitPictureInPicture() override {} void ExitPictureInPicture() override {}
void SetAudioSinkId(const base::Optional<std::string>& sink_id) 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);
......
...@@ -1071,6 +1071,8 @@ void MediaSessionImpl::ExitPictureInPicture() { ...@@ -1071,6 +1071,8 @@ void MediaSessionImpl::ExitPictureInPicture() {
normal_players_.begin()->first.player_id); normal_players_.begin()->first.player_id);
} }
void MediaSessionImpl::SetAudioSinkId(const base::Optional<std::string>& id) {}
void MediaSessionImpl::GetMediaImageBitmap( void MediaSessionImpl::GetMediaImageBitmap(
const media_session::MediaImage& image, const media_session::MediaImage& image,
int minimum_size_px, int minimum_size_px,
......
...@@ -253,6 +253,10 @@ class MediaSessionImpl : public MediaSession, ...@@ -253,6 +253,10 @@ class MediaSessionImpl : public MediaSession,
// Exit picture-in-picture. // Exit picture-in-picture.
void ExitPictureInPicture() override; void ExitPictureInPicture() override;
// Routes the audio from this Media Session to the given output device. If
// |id| is null, we will route to the default output device.
void SetAudioSinkId(const base::Optional<std::string>& id) 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.
......
...@@ -36,6 +36,7 @@ class FakeMediaSession : public content::MediaSession { ...@@ -36,6 +36,7 @@ class FakeMediaSession : public content::MediaSession {
MOCK_METHOD1(ScrubTo, void(base::TimeDelta)); MOCK_METHOD1(ScrubTo, void(base::TimeDelta));
MOCK_METHOD0(EnterPictureInPicture, void()); MOCK_METHOD0(EnterPictureInPicture, void());
MOCK_METHOD0(ExitPictureInPicture, void()); MOCK_METHOD0(ExitPictureInPicture, void());
MOCK_METHOD1(SetAudioSinkId, void(const base::Optional<std::string>& id));
// content::MediaSession APIs faked to implement testing behaviour. // content::MediaSession APIs faked to implement testing behaviour.
MOCK_METHOD1(DidReceiveAction, MOCK_METHOD1(DidReceiveAction,
......
...@@ -291,6 +291,13 @@ void MediaController::ExitPictureInPicture() { ...@@ -291,6 +291,13 @@ void MediaController::ExitPictureInPicture() {
session_->ipc()->ExitPictureInPicture(); session_->ipc()->ExitPictureInPicture();
} }
void MediaController::SetAudioSinkId(const base::Optional<std::string>& id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (session_)
session_->ipc()->SetAudioSinkId(id);
}
void MediaController::SetMediaSession(AudioFocusRequest* session) { void MediaController::SetMediaSession(AudioFocusRequest* session) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......
...@@ -53,6 +53,7 @@ class MediaController : public mojom::MediaController, ...@@ -53,6 +53,7 @@ class MediaController : public mojom::MediaController,
void ScrubTo(base::TimeDelta seek_time) override; void ScrubTo(base::TimeDelta seek_time) override;
void EnterPictureInPicture() override; void EnterPictureInPicture() override;
void ExitPictureInPicture() override; void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override;
// mojom::MediaSessionObserver overrides. // mojom::MediaSessionObserver overrides.
void MediaSessionInfoChanged( void MediaSessionInfoChanged(
......
...@@ -154,6 +154,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession ...@@ -154,6 +154,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
void ScrubTo(base::TimeDelta scrub_to) override; void ScrubTo(base::TimeDelta scrub_to) override;
void EnterPictureInPicture() override; void EnterPictureInPicture() override;
void ExitPictureInPicture() override; void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override {}
void SetIsControllable(bool value); void SetIsControllable(bool value);
void SetPreferStop(bool value) { prefer_stop_ = value; } void SetPreferStop(bool value) { prefer_stop_ = value; }
......
...@@ -155,6 +155,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) TestMediaController ...@@ -155,6 +155,7 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) TestMediaController
void ScrubTo(base::TimeDelta seek_time) override {} void ScrubTo(base::TimeDelta seek_time) override {}
void EnterPictureInPicture() override; void EnterPictureInPicture() override;
void ExitPictureInPicture() override; void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override {}
int toggle_suspend_resume_count() const { int toggle_suspend_resume_count() const {
return toggle_suspend_resume_count_; return toggle_suspend_resume_count_;
......
...@@ -83,6 +83,10 @@ interface MediaController { ...@@ -83,6 +83,10 @@ interface MediaController {
// Exit picture-in-picture. // Exit picture-in-picture.
ExitPictureInPicture(); ExitPictureInPicture();
// Routes the audio from this Media Session to the given output device. If
// |id| is null, we will route to the default output device.
SetAudioSinkId(string? id);
}; };
// The observer for observing media controller events. This is different to a // The observer for observing media controller events. This is different to a
......
...@@ -9,7 +9,7 @@ import "mojo/public/mojom/base/time.mojom"; ...@@ -9,7 +9,7 @@ import "mojo/public/mojom/base/time.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom";
import "url/mojom/url.mojom"; import "url/mojom/url.mojom";
// Next MinVersion: 9 // Next MinVersion: 10
[Extensible] [Extensible]
enum MediaPlaybackState { enum MediaPlaybackState {
...@@ -146,6 +146,11 @@ struct MediaSessionInfo { ...@@ -146,6 +146,11 @@ struct MediaSessionInfo {
// The audio/video state of the Media Session (if known). // The audio/video state of the Media Session (if known).
[MinVersion=8] MediaAudioVideoState audio_video_state; [MinVersion=8] MediaAudioVideoState audio_video_state;
// The audio_sink_id tells the client the device_id of the audio output device
// being used for this media session. A null audio_sink_id implies that the
// default device is being used.
[MinVersion=9] string? audio_sink_id;
}; };
// Contains debugging information about a MediaSession. This will be displayed // Contains debugging information about a MediaSession. This will be displayed
...@@ -188,7 +193,7 @@ interface MediaSessionObserver { ...@@ -188,7 +193,7 @@ interface MediaSessionObserver {
// WebContents or ARC app. // WebContents or ARC app.
// TODO(https://crbug.com/875004): migrate media session from content/public // TODO(https://crbug.com/875004): migrate media session from content/public
// to mojo. // to mojo.
// Next Method ID: 17 // Next Method ID: 18
interface MediaSession { interface MediaSession {
[Extensible] [Extensible]
enum SuspendType { enum SuspendType {
...@@ -270,4 +275,8 @@ interface MediaSession { ...@@ -270,4 +275,8 @@ interface MediaSession {
// Exit picture-in-picture. // Exit picture-in-picture.
ExitPictureInPicture@16(); ExitPictureInPicture@16();
// Routes the audio from this Media Session to the given output device. If
// |id| is null, we will route to the default output device.
SetAudioSinkId@17(string? id);
}; };
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