Commit 39536eb8 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Audio Focus] Request on focus

If we currently have audio focus we should re-request
audio focus when the web contents is focused. This
means with grouping the media session that was
last focused will be pushed to the top of the stack.

BUG=906285

Change-Id: I9a7a72897c3c7be1186bdfbc4ef87364f7744a20
Reviewed-on: https://chromium-review.googlesource.com/c/1347614
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611497}
parent c8e3546c
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/numerics/ranges.h" #include "base/numerics/ranges.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "build/build_config.h"
#include "content/browser/media/session/audio_focus_delegate.h" #include "content/browser/media/session/audio_focus_delegate.h"
#include "content/browser/media/session/media_session_controller.h" #include "content/browser/media/session/media_session_controller.h"
#include "content/browser/media/session/media_session_player_observer.h" #include "content/browser/media/session/media_session_player_observer.h"
...@@ -177,6 +178,17 @@ void MediaSessionImpl::DidFinishNavigation( ...@@ -177,6 +178,17 @@ void MediaSessionImpl::DidFinishNavigation(
services_[rfh]->DidFinishNavigation(); services_[rfh]->DidFinishNavigation();
} }
void MediaSessionImpl::OnWebContentsFocused(
RenderWidgetHost* render_widget_host) {
#if !defined(OS_ANDROID)
// If we have just gained focus and we have audio focus we should re-request
// system audio focus. This will ensure this media session is towards the top
// of the stack if we have multiple sessions active at the same time.
if (audio_focus_state_ == State::ACTIVE)
RequestSystemAudioFocus(desired_audio_focus_type_);
#endif
}
void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) { void MediaSessionImpl::AddObserver(MediaSessionObserver* observer) {
observers_.AddObserver(observer); observers_.AddObserver(observer);
NotifyAddedObserver(observer); NotifyAddedObserver(observer);
......
...@@ -134,6 +134,7 @@ class MediaSessionImpl : public MediaSession, ...@@ -134,6 +134,7 @@ class MediaSessionImpl : public MediaSession,
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
void RenderFrameDeleted(RenderFrameHost* rfh) override; void RenderFrameDeleted(RenderFrameHost* rfh) override;
void DidFinishNavigation(NavigationHandle* navigation_handle) override; void DidFinishNavigation(NavigationHandle* navigation_handle) override;
void OnWebContentsFocused(RenderWidgetHost* render_widget_host) override;
// MediaSessionService-related methods // MediaSessionService-related methods
......
...@@ -43,9 +43,12 @@ class MockAudioFocusDelegate : public AudioFocusDelegate { ...@@ -43,9 +43,12 @@ class MockAudioFocusDelegate : public AudioFocusDelegate {
~MockAudioFocusDelegate() override = default; ~MockAudioFocusDelegate() override = default;
void AbandonAudioFocus() override {} void AbandonAudioFocus() override {}
AudioFocusResult RequestAudioFocus(AudioFocusType type) override { AudioFocusResult RequestAudioFocus(AudioFocusType type) override {
request_audio_focus_count_++;
return AudioFocusResult::kSuccess; return AudioFocusResult::kSuccess;
} }
base::Optional<AudioFocusType> GetCurrentFocusType() const override { base::Optional<AudioFocusType> GetCurrentFocusType() const override {
return AudioFocusType::kGain; return AudioFocusType::kGain;
} }
...@@ -59,7 +62,11 @@ class MockAudioFocusDelegate : public AudioFocusDelegate { ...@@ -59,7 +62,11 @@ class MockAudioFocusDelegate : public AudioFocusDelegate {
return session_info_->state; return session_info_->state;
} }
int request_audio_focus_count() const { return request_audio_focus_count_; }
private: private:
int request_audio_focus_count_ = 0;
MediaSessionInfoPtr session_info_; MediaSessionInfoPtr session_info_;
DISALLOW_COPY_AND_ASSIGN(MockAudioFocusDelegate); DISALLOW_COPY_AND_ASSIGN(MockAudioFocusDelegate);
...@@ -409,6 +416,60 @@ TEST_F(MediaSessionImplTest, WebContentsDestroyed_StopsDucking) { ...@@ -409,6 +416,60 @@ TEST_F(MediaSessionImplTest, WebContentsDestroyed_StopsDucking) {
} }
} }
TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Active) {
std::unique_ptr<WebContents> web_contents(CreateWebContents());
MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate();
SetDelegateForTests(media_session, delegate);
{
MockMediaSessionMojoObserver observer(*media_session);
RequestAudioFocus(media_session, AudioFocusType::kGain);
FlushForTesting(media_session);
observer.WaitForState(MediaSessionInfo::SessionState::kActive);
}
EXPECT_EQ(1, delegate->request_audio_focus_count());
media_session->OnWebContentsFocused(nullptr);
EXPECT_EQ(2, delegate->request_audio_focus_count());
}
TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Inactive) {
std::unique_ptr<WebContents> web_contents(CreateWebContents());
MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate();
SetDelegateForTests(media_session, delegate);
EXPECT_EQ(MediaSessionInfo::SessionState::kInactive, GetState(media_session));
EXPECT_EQ(0, delegate->request_audio_focus_count());
media_session->OnWebContentsFocused(nullptr);
EXPECT_EQ(0, delegate->request_audio_focus_count());
}
TEST_F(MediaSessionImplTest, RequestAudioFocus_OnFocus_Suspended) {
std::unique_ptr<WebContents> web_contents(CreateWebContents());
MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate();
SetDelegateForTests(media_session, delegate);
{
MockMediaSessionMojoObserver observer(*media_session);
RequestAudioFocus(media_session, AudioFocusType::kGain);
FlushForTesting(media_session);
observer.WaitForState(MediaSessionInfo::SessionState::kActive);
}
{
MockMediaSessionMojoObserver observer(*media_session);
media_session->Suspend(MediaSession::SuspendType::kSystem);
observer.WaitForState(MediaSessionInfo::SessionState::kSuspended);
}
EXPECT_EQ(1, delegate->request_audio_focus_count());
media_session->OnWebContentsFocused(nullptr);
EXPECT_EQ(1, delegate->request_audio_focus_count());
}
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
} // namespace content } // namespace content
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