Skip to content

Commit

Permalink
Reland: PiP 1.5: Add video conferencing media session actions
Browse files Browse the repository at this point in the history
This is a reland of the CL to add video conferencing media session
actions. There is a switch statement in chrome-specific builds that
needed to be updated. Since this switch statement has caused reverts
every single time we've updated the enum and it actually only cares
about two of the values, I've updated it to just check for those two
values to avoid future switch statement compile issues.

Original CL description:
This CL adds new media session actions for video conferencing websites.
This CL also exposes methods to Blink for the MediaSessionServiceImpl
to get microphone and camera state from the website. This also exposes
those to users of the MediaSession service through MediaSessionImpl.

Design doc: https://docs.google.com/document/d/1KDpWqg9LcnuQ5TQDBK45BrbkyfuziolZ0m7Wmt6xPnU/edit?usp=sharing&resourcekey=0-I0o3GayIn9Q-2LN7EB1l8w

Bug: 1178939
Change-Id: I3299129db9647858ddc66257df0a1366c5b306cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2758052
Reviewed-by: Sean Topping <seantopping@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: Mounir Lamouri <mlamouri@chromium.org>
Commit-Queue: Tommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#863018}
  • Loading branch information
steimelchrome authored and Chromium LUCI CQ committed Mar 15, 2021
1 parent d563d85 commit 13732da
Show file tree
Hide file tree
Showing 28 changed files with 250 additions and 26 deletions.
3 changes: 3 additions & 0 deletions ash/login/ui/lock_screen_media_controls_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ const gfx::VectorIcon& GetVectorIconForMediaAction(MediaSessionAction action) {
case MediaSessionAction::kEnterPictureInPicture:
case MediaSessionAction::kExitPictureInPicture:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
NOTREACHED();
break;
}
Expand Down
3 changes: 3 additions & 0 deletions ash/system/media/unified_media_controls_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ const gfx::VectorIcon& GetVectorIconForMediaAction(MediaSessionAction action) {
case MediaSessionAction::kEnterPictureInPicture:
case MediaSessionAction::kExitPictureInPicture:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
NOTREACHED();
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ void CastMediaSessionController::Send(
case media_session::mojom::MediaSessionAction::kEnterPictureInPicture:
case media_session::mojom::MediaSessionAction::kExitPictureInPicture:
case media_session::mojom::MediaSessionAction::kSwitchAudioDevice:
case media_session::mojom::MediaSessionAction::kToggleMicrophone:
case media_session::mojom::MediaSessionAction::kToggleCamera:
case media_session::mojom::MediaSessionAction::kHangUp:
NOTREACHED();
return;
}
Expand Down
3 changes: 3 additions & 0 deletions chromecast/browser/cast_media_blocker_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class MockMediaSession : public content::MediaSession {
MOCK_METHOD0(EnterPictureInPicture, void());
MOCK_METHOD0(ExitPictureInPicture, void());
MOCK_METHOD1(SetAudioSinkId, void(const base::Optional<std::string>& id));
MOCK_METHOD0(ToggleMicrophone, void());
MOCK_METHOD0(ToggleCamera, void());
MOCK_METHOD0(HangUp, void());

private:
DISALLOW_COPY_AND_ASSIGN(MockMediaSession);
Expand Down
24 changes: 4 additions & 20 deletions chromeos/services/assistant/assistant_manager_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -342,26 +342,10 @@ void AssistantManagerServiceImpl::SyncDeviceAppsStatus() {

void AssistantManagerServiceImpl::UpdateInternalMediaPlayerStatus(
MediaSessionAction action) {
switch (action) {
case MediaSessionAction::kPause:
media_host_->PauseInternalMediaPlayer();
break;
case MediaSessionAction::kPlay:
media_host_->ResumeInternalMediaPlayer();
break;
case MediaSessionAction::kPreviousTrack:
case MediaSessionAction::kNextTrack:
case MediaSessionAction::kSeekBackward:
case MediaSessionAction::kSeekForward:
case MediaSessionAction::kSkipAd:
case MediaSessionAction::kStop:
case MediaSessionAction::kSeekTo:
case MediaSessionAction::kScrubTo:
case MediaSessionAction::kEnterPictureInPicture:
case MediaSessionAction::kExitPictureInPicture:
case MediaSessionAction::kSwitchAudioDevice:
NOTIMPLEMENTED();
break;
if (action == MediaSessionAction::kPause) {
media_host_->PauseInternalMediaPlayer();
} else if (action == MediaSessionAction::kPlay) {
media_host_->ResumeInternalMediaPlayer();
}
}

Expand Down
3 changes: 3 additions & 0 deletions chromeos/services/assistant/media_host_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ class MediaControllerMock : public media_session::mojom::MediaController {
MOCK_METHOD(void, EnterPictureInPicture, ());
MOCK_METHOD(void, ExitPictureInPicture, ());
MOCK_METHOD(void, SetAudioSinkId, (const base::Optional<std::string>& id));
MOCK_METHOD(void, ToggleMicrophone, ());
MOCK_METHOD(void, ToggleCamera, ());
MOCK_METHOD(void, HangUp, ());
void AddObserver(
mojo::PendingRemote<media_session::mojom::MediaControllerObserver> remote)
override {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class COMPONENT_EXPORT(ASSISTANT_SERVICE) AssistantMediaSession
void EnterPictureInPicture() override {}
void ExitPictureInPicture() override {}
void SetAudioSinkId(const base::Optional<std::string>& sink_id) override {}
void ToggleMicrophone() override {}
void ToggleCamera() override {}
void HangUp() override {}

// Requests/abandons audio focus to the AudioFocusManager.
void RequestAudioFocus(media_session::mojom::AudioFocusType audio_focus_type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ const gfx::VectorIcon* GetVectorIconForMediaAction(MediaSessionAction action) {
case MediaSessionAction::kSeekTo:
case MediaSessionAction::kScrubTo:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
NOTREACHED();
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ const gfx::VectorIcon* GetVectorIconForMediaAction(MediaSessionAction action) {
case MediaSessionAction::kSeekTo:
case MediaSessionAction::kScrubTo:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
NOTREACHED();
break;
}
Expand Down
6 changes: 6 additions & 0 deletions content/browser/media/active_media_session_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ void ActiveMediaSessionController::PerformAction(MediaSessionAction action) {
case MediaSessionAction::kEnterPictureInPicture:
case MediaSessionAction::kExitPictureInPicture:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
NOTREACHED();
return;
}
Expand Down Expand Up @@ -239,6 +242,9 @@ ActiveMediaSessionController::MediaSessionActionToKeyCode(
case MediaSessionAction::kEnterPictureInPicture:
case MediaSessionAction::kExitPictureInPicture:
case MediaSessionAction::kSwitchAudioDevice:
case MediaSessionAction::kToggleMicrophone:
case MediaSessionAction::kToggleCamera:
case MediaSessionAction::kHangUp:
return base::nullopt;
}
}
Expand Down
34 changes: 34 additions & 0 deletions content/browser/media/session/media_session_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ MediaSessionUserAction MediaSessionActionToUserAction(
return MediaSessionUserAction::ExitPictureInPicture;
case media_session::mojom::MediaSessionAction::kSwitchAudioDevice:
return MediaSessionUserAction::SwitchAudioDevice;
case media_session::mojom::MediaSessionAction::kToggleMicrophone:
return MediaSessionUserAction::ToggleMicrophone;
case media_session::mojom::MediaSessionAction::kToggleCamera:
return MediaSessionUserAction::ToggleCamera;
case media_session::mojom::MediaSessionAction::kHangUp:
return MediaSessionUserAction::HangUp;
}
NOTREACHED();
return MediaSessionUserAction::Play;
Expand Down Expand Up @@ -986,6 +992,14 @@ MediaSessionImpl::GetMediaSessionInfoSync() {
if (shared_audio_device_id != media::AudioDeviceDescription::kDefaultDeviceId)
info->audio_sink_id = shared_audio_device_id;

if (routed_service_) {
info->microphone_state = routed_service_->microphone_state();
info->camera_state = routed_service_->camera_state();
} else {
info->microphone_state = media_session::mojom::MicrophoneState::kUnknown;
info->camera_state = media_session::mojom::CameraState::kUnknown;
}

return info;
}

Expand Down Expand Up @@ -1110,6 +1124,18 @@ void MediaSessionImpl::SetAudioSinkId(const base::Optional<std::string>& id) {
}
}

void MediaSessionImpl::ToggleMicrophone() {
DidReceiveAction(media_session::mojom::MediaSessionAction::kToggleMicrophone);
}

void MediaSessionImpl::ToggleCamera() {
DidReceiveAction(media_session::mojom::MediaSessionAction::kToggleCamera);
}

void MediaSessionImpl::HangUp() {
DidReceiveAction(media_session::mojom::MediaSessionAction::kHangUp);
}

void MediaSessionImpl::GetMediaImageBitmap(
const media_session::MediaImage& image,
int minimum_size_px,
Expand Down Expand Up @@ -1284,6 +1310,14 @@ void MediaSessionImpl::OnMediaSessionActionsChanged(
RebuildAndNotifyActionsChanged();
}

void MediaSessionImpl::OnMediaSessionInfoChanged(
MediaSessionServiceImpl* service) {
if (service != routed_service_)
return;

RebuildAndNotifyMediaSessionInfoChanged();
}

void MediaSessionImpl::DidReceiveAction(
media_session::mojom::MediaSessionAction action) {
DidReceiveAction(action, nullptr /* details */);
Expand Down
14 changes: 14 additions & 0 deletions content/browser/media/session/media_session_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,15 @@ class MediaSessionImpl : public MediaSession,
// Called when the metadata of a MediaSessionService has changed. Will notify
// observers if the service is currently routed.
void OnMediaSessionMetadataChanged(MediaSessionServiceImpl* service);

// Called when the actions of a MediaSessionService has changed. Will notify
// observers if the service is currently routed.
void OnMediaSessionActionsChanged(MediaSessionServiceImpl* service);

// Called when the info of a MediaSessionService has changed. Will notify
// observers if the service is currently routed.
void OnMediaSessionInfoChanged(MediaSessionServiceImpl* service);

// Requests audio focus to the AudioFocusDelegate.
// Returns whether the request was granted.
CONTENT_EXPORT AudioFocusDelegate::AudioFocusResult RequestSystemAudioFocus(
Expand Down Expand Up @@ -262,6 +267,15 @@ class MediaSessionImpl : public MediaSession,
// this method is called again.
void SetAudioSinkId(const base::Optional<std::string>& id) override;

// Mute/Unmute the microphone for a WebRTC session.
void ToggleMicrophone() override;

// Turn on or off the camera for a WebRTC session.
void ToggleCamera() override;

// Hang up a WebRTC session.
void HangUp() override;

// 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
// the image did not come from the media session then returns a null image.
Expand Down
16 changes: 16 additions & 0 deletions content/browser/media/session/media_session_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ void MediaSessionServiceImpl::SetMetadata(
session->OnMediaSessionMetadataChanged(this);
}

void MediaSessionServiceImpl::SetMicrophoneState(
media_session::mojom::MicrophoneState microphone_state) {
microphone_state_ = microphone_state;
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionInfoChanged(this);
}

void MediaSessionServiceImpl::SetCameraState(
media_session::mojom::CameraState camera_state) {
camera_state_ = camera_state;
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionInfoChanged(this);
}

void MediaSessionServiceImpl::EnableAction(
media_session::mojom::MediaSessionAction action) {
actions_.insert(action);
Expand Down
17 changes: 17 additions & 0 deletions content/browser/media/session/media_session_service_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class CONTENT_EXPORT MediaSessionServiceImpl
const base::Optional<media_session::MediaPosition>& position() const {
return position_;
}
media_session::mojom::MicrophoneState microphone_state() const {
return microphone_state_;
}
media_session::mojom::CameraState camera_state() const {
return camera_state_;
}

void DidFinishNavigation();
void FlushForTesting();
Expand All @@ -57,6 +63,9 @@ class CONTENT_EXPORT MediaSessionServiceImpl
void SetPositionState(
const base::Optional<media_session::MediaPosition>& position) override;
void SetMetadata(blink::mojom::SpecMediaMetadataPtr metadata) override;
void SetMicrophoneState(
media_session::mojom::MicrophoneState microphone_state) override;
void SetCameraState(media_session::mojom::CameraState camera_state) override;

void EnableAction(media_session::mojom::MediaSessionAction action) override;
void DisableAction(media_session::mojom::MediaSessionAction action) override;
Expand All @@ -83,6 +92,14 @@ class CONTENT_EXPORT MediaSessionServiceImpl
std::set<media_session::mojom::MediaSessionAction> actions_;
base::Optional<media_session::MediaPosition> position_;

// Tracks whether the microphone is muted in a WebRTC session.
media_session::mojom::MicrophoneState microphone_state_ =
media_session::mojom::MicrophoneState::kUnknown;

// Tracks whether the camera is turned on in a WebRTC session.
media_session::mojom::CameraState camera_state_ =
media_session::mojom::CameraState::kUnknown;

DISALLOW_COPY_AND_ASSIGN(MediaSessionServiceImpl);
};

Expand Down
5 changes: 4 additions & 1 deletion content/browser/media/session/media_session_uma_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ class CONTENT_EXPORT MediaSessionUmaHelper {
EnterPictureInPicture = 13,
ExitPictureInPicture = 14,
SwitchAudioDevice = 15,
kMaxValue = SwitchAudioDevice,
ToggleMicrophone = 16,
ToggleCamera = 17,
HangUp = 18,
kMaxValue = HangUp,
};

MediaSessionUmaHelper();
Expand Down
6 changes: 6 additions & 0 deletions fuchsia/engine/browser/media_player_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ fuchsia::media::sessions2::PlayerCapabilityFlags ActionToCapabilityFlag(
return {}; // PlayerControl assumes that stop is always supported.
case MediaSessionAction::kSwitchAudioDevice:
return {}; // PlayerControl does not support switching audio device.
case MediaSessionAction::kToggleMicrophone:
return {}; // PlayerControl does not support toggling microphone.
case MediaSessionAction::kToggleCamera:
return {}; // PlayerControl does not support toggling camera.
case MediaSessionAction::kHangUp:
return {}; // PlayerControl does not support hanging up.
}
}

Expand Down
3 changes: 3 additions & 0 deletions fuchsia/engine/browser/media_player_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class FakeMediaSession : public content::MediaSession {
MOCK_METHOD0(EnterPictureInPicture, void());
MOCK_METHOD0(ExitPictureInPicture, void());
MOCK_METHOD1(SetAudioSinkId, void(const base::Optional<std::string>& id));
MOCK_METHOD0(ToggleMicrophone, void());
MOCK_METHOD0(ToggleCamera, void());
MOCK_METHOD0(HangUp, void());

// content::MediaSession APIs faked to implement testing behaviour.
MOCK_METHOD1(DidReceiveAction,
Expand Down
21 changes: 21 additions & 0 deletions services/media_session/media_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,27 @@ void MediaController::SetAudioSinkId(const base::Optional<std::string>& id) {
session_->ipc()->SetAudioSinkId(id);
}

void MediaController::ToggleMicrophone() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

if (session_)
session_->ipc()->ToggleMicrophone();
}

void MediaController::ToggleCamera() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

if (session_)
session_->ipc()->ToggleCamera();
}

void MediaController::HangUp() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

if (session_)
session_->ipc()->HangUp();
}

void MediaController::SetMediaSession(AudioFocusRequest* session) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

Expand Down
3 changes: 3 additions & 0 deletions services/media_session/media_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class MediaController : public mojom::MediaController,
void EnterPictureInPicture() override;
void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override;
void ToggleMicrophone() override;
void ToggleCamera() override;
void HangUp() override;

// mojom::MediaSessionObserver overrides.
void MediaSessionInfoChanged(
Expand Down
3 changes: 3 additions & 0 deletions services/media_session/public/cpp/test/mock_media_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) MockMediaSession
void EnterPictureInPicture() override;
void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override {}
void ToggleMicrophone() override {}
void ToggleCamera() override {}
void HangUp() override {}

void SetIsControllable(bool value);
void SetPreferStop(bool value) { prefer_stop_ = value; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ class COMPONENT_EXPORT(MEDIA_SESSION_TEST_SUPPORT_CPP) TestMediaController
void EnterPictureInPicture() override;
void ExitPictureInPicture() override;
void SetAudioSinkId(const base::Optional<std::string>& id) override {}
void ToggleMicrophone() override {}
void ToggleCamera() override {}
void HangUp() override {}

int toggle_suspend_resume_count() const {
return toggle_suspend_resume_count_;
Expand Down
9 changes: 9 additions & 0 deletions services/media_session/public/cpp/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ void PerformMediaSessionAction(
case mojom::MediaSessionAction::kExitPictureInPicture:
media_controller_remote->ExitPictureInPicture();
break;
case mojom::MediaSessionAction::kToggleMicrophone:
media_controller_remote->ToggleMicrophone();
break;
case mojom::MediaSessionAction::kToggleCamera:
media_controller_remote->ToggleCamera();
break;
case mojom::MediaSessionAction::kHangUp:
media_controller_remote->HangUp();
break;
case mojom::MediaSessionAction::kSkipAd:
case mojom::MediaSessionAction::kSeekTo:
case mojom::MediaSessionAction::kScrubTo:
Expand Down
Loading

0 comments on commit 13732da

Please sign in to comment.