| Index: content/browser/media/session/media_session_service_impl_browsertest.cc
|
| diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc
|
| index 959bbaeff65482c07fe91745e11c8cafe30dca78..cfbdef154d6375106624bb47829e1eb0d21f1c30 100644
|
| --- a/content/browser/media/session/media_session_service_impl_browsertest.cc
|
| +++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
|
| @@ -2,19 +2,139 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "content/browser/media/session/media_session_service_impl.h"
|
| +
|
| #include "base/command_line.h"
|
| +#include "base/run_loop.h"
|
| +#include "content/browser/media/session/media_session_impl.h"
|
| +#include "content/browser/media/session/media_session_player_observer.h"
|
| +#include "content/public/browser/web_contents_observer.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| #include "content/public/test/content_browser_test.h"
|
| #include "content/public/test/content_browser_test_utils.h"
|
| #include "content/shell/browser/shell.h"
|
| +#include "media/base/media_content_type.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +class MockMediaSessionObserver : public MediaSessionObserver {
|
| + public:
|
| + explicit MockMediaSessionObserver(
|
| + MediaSession* session,
|
| + const base::Closure& closure_on_actions_change)
|
| + : MediaSessionObserver(session),
|
| + closure_on_actions_change_(closure_on_actions_change) {}
|
| +
|
| + void MediaSessionActionsChanged(
|
| + const std::set<blink::mojom::MediaSessionAction>& actions) override {
|
| + // The actions might be empty when the service becomes routed for the first
|
| + // time.
|
| + if (actions.size() == 1)
|
| + closure_on_actions_change_.Run();
|
| + }
|
| +
|
| + private:
|
| + base::Closure closure_on_actions_change_;
|
| +};
|
| +
|
| +class MockWebContentsObserver : public WebContentsObserver {
|
| + public:
|
| + explicit MockWebContentsObserver(WebContents* contents,
|
| + const base::Closure& closure_on_navigate)
|
| + : WebContentsObserver(contents),
|
| + closure_on_navigate_(closure_on_navigate) {}
|
| +
|
| + void DidFinishNavigation(NavigationHandle* navigation_handle) override {
|
| + closure_on_navigate_.Run();
|
| + }
|
| +
|
| + private:
|
| + base::Closure closure_on_navigate_;
|
| +};
|
| +
|
| +class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
|
| + public:
|
| + explicit MockMediaSessionPlayerObserver(RenderFrameHost* rfh)
|
| + : render_frame_host_(rfh) {}
|
| +
|
| + ~MockMediaSessionPlayerObserver() override = default;
|
| +
|
| + void OnSuspend(int player_id) override {}
|
| + void OnResume(int player_id) override {}
|
| + void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override {
|
| + }
|
| +
|
| + RenderFrameHost* GetRenderFrameHost() const override {
|
| + return render_frame_host_;
|
| + }
|
| +
|
| + private:
|
| + RenderFrameHost* render_frame_host_;
|
| +};
|
| +
|
| +void NavigateToURLAndWaitForFinish(Shell* window, const GURL& url) {
|
| + base::RunLoop run_loop;
|
| + MockWebContentsObserver observer(window->web_contents(),
|
| + run_loop.QuitClosure());
|
| +
|
| + NavigateToURL(window, url);
|
| + run_loop.Run();
|
| +}
|
| +
|
| +char kSetUpMediaSessionScript[] =
|
| + "navigator.mediaSession.playbackState = \"playing\";\n"
|
| + "navigator.mediaSession.metadata = new MediaMetadata({ title: \"foo\" });\n"
|
| + "navigator.mediaSession.setActionHandler(\"play\", _ => {});";
|
| +
|
| +const int kPlayerId = 0;
|
| +
|
| +} // anonymous namespace
|
| +
|
| class MediaSessionServiceImplBrowserTest : public ContentBrowserTest {
|
| protected:
|
| void SetUpCommandLine(base::CommandLine* command_line) override {
|
| ContentBrowserTest::SetUpCommandLine(command_line);
|
| command_line->AppendSwitchASCII("--enable-blink-features", "MediaSession");
|
| }
|
| +
|
| + void EnsurePlayer() {
|
| + if (player_)
|
| + return;
|
| +
|
| + player_.reset(new MockMediaSessionPlayerObserver(
|
| + shell()->web_contents()->GetMainFrame()));
|
| +
|
| + MediaSessionImpl::Get(shell()->web_contents())
|
| + ->AddPlayer(player_.get(), kPlayerId,
|
| + media::MediaContentType::Persistent);
|
| + }
|
| +
|
| + MediaSessionImpl* GetSession() {
|
| + return MediaSessionImpl::Get(shell()->web_contents());
|
| + }
|
| +
|
| + MediaSessionServiceImpl* GetService() {
|
| + RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
|
| + if (GetSession()->services_.count(main_frame))
|
| + return GetSession()->services_[main_frame];
|
| +
|
| + return nullptr;
|
| + }
|
| +
|
| + bool ExecuteScriptToSetUpMediaSessionSync() {
|
| + // Using the actions change as the signal of completion.
|
| + base::RunLoop run_loop;
|
| + MockMediaSessionObserver observer(GetSession(), run_loop.QuitClosure());
|
| + bool result = ExecuteScript(shell(), kSetUpMediaSessionScript);
|
| + run_loop.Run();
|
| + return result;
|
| + }
|
| +
|
| + private:
|
| + std::unique_ptr<MockMediaSessionPlayerObserver> player_;
|
| };
|
|
|
| // Two windows from the same BrowserContext.
|
| @@ -26,4 +146,51 @@ IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
|
| // Should not crash.
|
| }
|
|
|
| +// Tests for checking if the media session service members are correctly reset
|
| +// when navigating. Due to the mojo services have different message queues, it's
|
| +// hard to wait for the messages to arrive. Temporarily, the tests are using
|
| +// observers to wait for the message to be processed on the MediaSessionObserver
|
| +// side.
|
| +
|
| +IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
|
| + ResetServiceWhenNavigatingAway) {
|
| + NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
|
| + EnsurePlayer();
|
| +
|
| + EXPECT_TRUE(ExecuteScriptToSetUpMediaSessionSync());
|
| +
|
| + EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::PLAYING,
|
| + GetService()->playback_state());
|
| + EXPECT_TRUE(GetService()->metadata().has_value());
|
| + EXPECT_EQ(1u, GetService()->actions().size());
|
| +
|
| + // Start a non-same-page navigation and check the playback state, metadata,
|
| + // actions are reset.
|
| + NavigateToURLAndWaitForFinish(shell(), GetTestUrl(".", "title2.html"));
|
| +
|
| + EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::NONE,
|
| + GetService()->playback_state());
|
| + EXPECT_FALSE(GetService()->metadata().has_value());
|
| + EXPECT_EQ(0u, GetService()->actions().size());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
|
| + DontResetServiceForSamePageNavigation) {
|
| + NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
|
| + EnsurePlayer();
|
| +
|
| + EXPECT_TRUE(ExecuteScriptToSetUpMediaSessionSync());
|
| +
|
| + // Start a same-page navigation and check the playback state, metadata,
|
| + // actions are not reset.
|
| + GURL same_page_url = GetTestUrl(".", "title1.html");
|
| + same_page_url = GURL(same_page_url.spec() + "#some-anchor");
|
| + NavigateToURLAndWaitForFinish(shell(), same_page_url);
|
| +
|
| + EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::PLAYING,
|
| + GetService()->playback_state());
|
| + EXPECT_TRUE(GetService()->metadata().has_value());
|
| + EXPECT_EQ(1u, GetService()->actions().size());
|
| +}
|
| +
|
| } // namespace content
|
|
|