Commit bbfd9929 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Session] Trigger action on play / pause

At the moment on Android we trigger the kPlay or kPause
actions if they are registered. This moves that logic
a layer down to C++ so it will work for keyboard
controls too.

BUG=894255

Change-Id: I0eae3ac51b7d772643ab2a56091e3f0ddb6b2325
Reviewed-on: https://chromium-review.googlesource.com/c/1404178Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622044}
parent e49e37b6
...@@ -94,15 +94,9 @@ public class MediaSessionTabHelper implements MediaImageCallback { ...@@ -94,15 +94,9 @@ public class MediaSessionTabHelper implements MediaImageCallback {
MediaSessionUMA.recordPlay( MediaSessionUMA.recordPlay(
MediaSessionTabHelper.convertMediaActionSourceToUMA(actionSource)); MediaSessionTabHelper.convertMediaActionSourceToUMA(actionSource));
if (mMediaSessionObserver.getMediaSession() != null) { if (mMediaSessionObserver.getMediaSession() == null) return;
if (mMediaSessionActions != null
&& mMediaSessionActions.contains(MediaSessionAction.PLAY)) { mMediaSessionObserver.getMediaSession().resume();
mMediaSessionObserver.getMediaSession()
.didReceiveAction(MediaSessionAction.PLAY);
} else {
mMediaSessionObserver.getMediaSession().resume();
}
}
} }
@Override @Override
...@@ -112,15 +106,9 @@ public class MediaSessionTabHelper implements MediaImageCallback { ...@@ -112,15 +106,9 @@ public class MediaSessionTabHelper implements MediaImageCallback {
MediaSessionUMA.recordPause( MediaSessionUMA.recordPause(
MediaSessionTabHelper.convertMediaActionSourceToUMA(actionSource)); MediaSessionTabHelper.convertMediaActionSourceToUMA(actionSource));
if (mMediaSessionObserver.getMediaSession() != null) { if (mMediaSessionObserver.getMediaSession() == null) return;
if (mMediaSessionActions != null
&& mMediaSessionActions.contains(MediaSessionAction.PAUSE)) { mMediaSessionObserver.getMediaSession().suspend();
mMediaSessionObserver.getMediaSession()
.didReceiveAction(MediaSessionAction.PAUSE);
} else {
mMediaSessionObserver.getMediaSession().suspend();
}
}
} }
@Override @Override
......
...@@ -402,6 +402,13 @@ void MediaSessionImpl::Resume(SuspendType suspend_type) { ...@@ -402,6 +402,13 @@ void MediaSessionImpl::Resume(SuspendType suspend_type) {
return; return;
if (suspend_type == SuspendType::kUI) { if (suspend_type == SuspendType::kUI) {
// If the site has registered an action handler for play then we should
// pass it to the site and let them handle it.
if (IsActionSupported(media_session::mojom::MediaSessionAction::kPlay)) {
DidReceiveAction(media_session::mojom::MediaSessionAction::kPlay);
return;
}
MediaSessionUmaHelper::RecordMediaSessionUserAction( MediaSessionUmaHelper::RecordMediaSessionUserAction(
MediaSessionUmaHelper::MediaSessionUserAction::PlayDefault); MediaSessionUmaHelper::MediaSessionUserAction::PlayDefault);
} }
...@@ -431,6 +438,13 @@ void MediaSessionImpl::Suspend(SuspendType suspend_type) { ...@@ -431,6 +438,13 @@ void MediaSessionImpl::Suspend(SuspendType suspend_type) {
return; return;
if (suspend_type == SuspendType::kUI) { if (suspend_type == SuspendType::kUI) {
// If the site has registered an action handler for pause then we should
// pass it to the site and let them handle it.
if (IsActionSupported(media_session::mojom::MediaSessionAction::kPause)) {
DidReceiveAction(media_session::mojom::MediaSessionAction::kPause);
return;
}
MediaSessionUmaHelper::RecordMediaSessionUserAction( MediaSessionUmaHelper::RecordMediaSessionUserAction(
MediaSessionUserAction::PauseDefault); MediaSessionUserAction::PauseDefault);
} }
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h" #include "base/test/simple_test_tick_clock.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_service_impl.h"
#include "content/browser/media/session/mock_media_session_observer.h" #include "content/browser/media/session/mock_media_session_observer.h"
#include "content/browser/media/session/mock_media_session_player_observer.h" #include "content/browser/media/session/mock_media_session_player_observer.h"
#include "content/browser/media/session/mock_media_session_service_impl.h"
#include "content/public/browser/media_session.h" #include "content/public/browser/media_session.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
...@@ -96,13 +96,6 @@ class MockAudioFocusDelegate : public AudioFocusDelegate { ...@@ -96,13 +96,6 @@ class MockAudioFocusDelegate : public AudioFocusDelegate {
base::Optional<AudioFocusType> audio_focus_type_; base::Optional<AudioFocusType> audio_focus_type_;
}; };
class MockMediaSessionServiceImpl : public content::MediaSessionServiceImpl {
public:
explicit MockMediaSessionServiceImpl(content::RenderFrameHost* rfh)
: MediaSessionServiceImpl(rfh) {}
~MockMediaSessionServiceImpl() override = default;
};
} // namespace } // namespace
class MediaSessionImplBrowserTest : public content::ContentBrowserTest { class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
...@@ -197,8 +190,9 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest { ...@@ -197,8 +190,9 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
void SystemStopDucking() { media_session_->StopDucking(); } void SystemStopDucking() { media_session_->StopDucking(); }
void EnsureMediaSessionService() { void EnsureMediaSessionService() {
mock_media_session_service_.reset(new NiceMock<MockMediaSessionServiceImpl>( mock_media_session_service_.reset(
shell()->web_contents()->GetMainFrame())); new NiceMock<content::MockMediaSessionServiceImpl>(
shell()->web_contents()->GetMainFrame()));
} }
void SetPlaybackState(blink::mojom::MediaSessionPlaybackState state) { void SetPlaybackState(blink::mojom::MediaSessionPlaybackState state) {
...@@ -246,7 +240,8 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest { ...@@ -246,7 +240,8 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
std::unique_ptr<content::MockMediaSessionObserver> std::unique_ptr<content::MockMediaSessionObserver>
mock_media_session_observer_; mock_media_session_observer_;
MockAudioFocusDelegate* mock_audio_focus_delegate_; MockAudioFocusDelegate* mock_audio_focus_delegate_;
std::unique_ptr<MockMediaSessionServiceImpl> mock_media_session_service_; std::unique_ptr<content::MockMediaSessionServiceImpl>
mock_media_session_service_;
DISALLOW_COPY_AND_ASSIGN(MediaSessionImplBrowserTest); DISALLOW_COPY_AND_ASSIGN(MediaSessionImplBrowserTest);
}; };
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "content/browser/media/session/media_session_player_observer.h" #include "content/browser/media/session/media_session_player_observer.h"
#include "content/browser/media/session/media_session_service_impl.h"
#include "content/browser/media/session/mock_media_session_observer.h" #include "content/browser/media/session/mock_media_session_observer.h"
#include "content/browser/media/session/mock_media_session_service_impl.h"
#include "content/public/test/test_service_manager_context.h" #include "content/public/test/test_service_manager_context.h"
#include "content/test/test_render_view_host.h" #include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h" #include "content/test/test_web_contents.h"
...@@ -37,32 +37,6 @@ constexpr base::TimeDelta kDefaultSeekTime = ...@@ -37,32 +37,6 @@ constexpr base::TimeDelta kDefaultSeekTime =
static const int kPlayerId = 0; static const int kPlayerId = 0;
class MockMediaSessionServiceImpl : public MediaSessionServiceImpl {
public:
explicit MockMediaSessionServiceImpl(RenderFrameHost* rfh)
: MediaSessionServiceImpl(rfh) {}
~MockMediaSessionServiceImpl() override = default;
};
class MockMediaSessionClient : public blink::mojom::MediaSessionClient {
public:
MockMediaSessionClient() : binding_(this) {}
blink::mojom::MediaSessionClientPtr CreateInterfacePtrAndBind() {
blink::mojom::MediaSessionClientPtr client;
binding_.Bind(mojo::MakeRequest(&client));
return client;
}
MOCK_METHOD1(DidReceiveAction,
void(media_session::mojom::MediaSessionAction action));
private:
mojo::Binding<blink::mojom::MediaSessionClient> binding_;
DISALLOW_COPY_AND_ASSIGN(MockMediaSessionClient);
};
class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver { class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
public: public:
explicit MockMediaSessionPlayerObserver(RenderFrameHost* rfh) explicit MockMediaSessionPlayerObserver(RenderFrameHost* rfh)
...@@ -109,7 +83,6 @@ class MediaSessionImplServiceRoutingTest ...@@ -109,7 +83,6 @@ class MediaSessionImplServiceRoutingTest
void TearDown() override { void TearDown() override {
mock_media_session_observer_.reset(); mock_media_session_observer_.reset();
services_.clear(); services_.clear();
clients_.clear();
test_service_manager_context_.reset(); test_service_manager_context_.reset();
RenderViewHostImplTestHarness::TearDown(); RenderViewHostImplTestHarness::TearDown();
...@@ -123,18 +96,16 @@ class MediaSessionImplServiceRoutingTest ...@@ -123,18 +96,16 @@ class MediaSessionImplServiceRoutingTest
void CreateServiceForFrame(TestRenderFrameHost* frame) { void CreateServiceForFrame(TestRenderFrameHost* frame) {
services_[frame] = services_[frame] =
std::make_unique<NiceMock<MockMediaSessionServiceImpl>>(frame); std::make_unique<NiceMock<MockMediaSessionServiceImpl>>(frame);
clients_[frame] = std::make_unique<NiceMock<MockMediaSessionClient>>();
services_[frame]->SetClient(clients_[frame]->CreateInterfacePtrAndBind());
} }
void DestroyServiceForFrame(TestRenderFrameHost* frame) { void DestroyServiceForFrame(TestRenderFrameHost* frame) {
services_.erase(frame); services_.erase(frame);
clients_.erase(frame);
} }
MockMediaSessionClient* GetClientForFrame(TestRenderFrameHost* frame) { MockMediaSessionClient* GetClientForFrame(TestRenderFrameHost* frame) {
auto iter = clients_.find(frame); auto iter = services_.find(frame);
return (iter != clients_.end()) ? iter->second.get() : nullptr; return (iter != services_.end()) ? &iter->second.get()->mock_client()
: nullptr;
} }
void StartPlayerForFrame(TestRenderFrameHost* frame) { void StartPlayerForFrame(TestRenderFrameHost* frame) {
...@@ -176,10 +147,6 @@ class MediaSessionImplServiceRoutingTest ...@@ -176,10 +147,6 @@ class MediaSessionImplServiceRoutingTest
std::unique_ptr<MockMediaSessionServiceImpl>>; std::unique_ptr<MockMediaSessionServiceImpl>>;
ServiceMap services_; ServiceMap services_;
using ClientMap =
std::map<TestRenderFrameHost*, std::unique_ptr<MockMediaSessionClient>>;
ClientMap clients_;
using PlayerMap = std::map<TestRenderFrameHost*, using PlayerMap = std::map<TestRenderFrameHost*,
std::unique_ptr<MockMediaSessionPlayerObserver>>; std::unique_ptr<MockMediaSessionPlayerObserver>>;
PlayerMap players_; PlayerMap players_;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/metrics/histogram_samples.h" #include "base/metrics/histogram_samples.h"
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "content/browser/media/session/media_session_player_observer.h" #include "content/browser/media/session/media_session_player_observer.h"
#include "content/browser/media/session/mock_media_session_service_impl.h"
#include "content/public/test/test_service_manager_context.h" #include "content/public/test/test_service_manager_context.h"
#include "content/test/test_render_view_host.h" #include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h" #include "content/test/test_web_contents.h"
...@@ -77,9 +78,14 @@ class MediaSessionImplUmaTest : public RenderViewHostImplTestHarness { ...@@ -77,9 +78,14 @@ class MediaSessionImplUmaTest : public RenderViewHostImplTestHarness {
contents()->GetMainFrame()->InitializeRenderFrameIfNeeded(); contents()->GetMainFrame()->InitializeRenderFrameIfNeeded();
StartPlayer(); StartPlayer();
mock_media_session_service_.reset(
new testing::NiceMock<MockMediaSessionServiceImpl>(
contents()->GetMainFrame()));
} }
void TearDown() override { void TearDown() override {
mock_media_session_service_.reset();
test_service_manager_context_.reset(); test_service_manager_context_.reset();
RenderViewHostImplTestHarness::TearDown(); RenderViewHostImplTestHarness::TearDown();
} }
...@@ -99,6 +105,7 @@ class MediaSessionImplUmaTest : public RenderViewHostImplTestHarness { ...@@ -99,6 +105,7 @@ class MediaSessionImplUmaTest : public RenderViewHostImplTestHarness {
return histogram_tester_.GetHistogramSamplesSinceCreation(name); return histogram_tester_.GetHistogramSamplesSinceCreation(name);
} }
std::unique_ptr<MockMediaSessionServiceImpl> mock_media_session_service_;
std::unique_ptr<MockMediaSessionPlayerObserver> player_; std::unique_ptr<MockMediaSessionPlayerObserver> player_;
base::HistogramTester histogram_tester_; base::HistogramTester histogram_tester_;
...@@ -116,6 +123,19 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUISuspend) { ...@@ -116,6 +123,19 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUISuspend) {
MediaSessionUserAction::PauseDefault))); MediaSessionUserAction::PauseDefault)));
} }
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUISuspendWithAction) {
mock_media_session_service_->EnableAction(
media_session::mojom::MediaSessionAction::kPause);
GetSession()->Suspend(SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(1, samples->TotalCount());
EXPECT_EQ(1, samples->GetCount(static_cast<base::HistogramBase::Sample>(
MediaSessionUserAction::Pause)));
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemSuspend) { TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemSuspend) {
GetSession()->Suspend(SuspendType::kSystem); GetSession()->Suspend(SuspendType::kSystem);
std::unique_ptr<base::HistogramSamples> samples( std::unique_ptr<base::HistogramSamples> samples(
...@@ -140,6 +160,20 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIResume) { ...@@ -140,6 +160,20 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIResume) {
MediaSessionUserAction::PlayDefault))); MediaSessionUserAction::PlayDefault)));
} }
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIResumeWithAction) {
mock_media_session_service_->EnableAction(
media_session::mojom::MediaSessionAction::kPlay);
GetSession()->Suspend(SuspendType::kSystem);
GetSession()->Resume(SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(1, samples->TotalCount());
EXPECT_EQ(1, samples->GetCount(static_cast<base::HistogramBase::Sample>(
MediaSessionUserAction::Play)));
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemResume) { TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemResume) {
GetSession()->Suspend(SuspendType::kSystem); GetSession()->Suspend(SuspendType::kSystem);
GetSession()->Resume(SuspendType::kSystem); GetSession()->Resume(SuspendType::kSystem);
......
...@@ -51,6 +51,10 @@ void MediaSessionServiceImpl::DidFinishNavigation() { ...@@ -51,6 +51,10 @@ void MediaSessionServiceImpl::DidFinishNavigation() {
ClearActions(); ClearActions();
} }
void MediaSessionServiceImpl::FlushForTesting() {
client_.FlushForTesting();
}
void MediaSessionServiceImpl::SetClient( void MediaSessionServiceImpl::SetClient(
blink::mojom::MediaSessionClientPtr client) { blink::mojom::MediaSessionClientPtr client) {
client_ = std::move(client); client_ = std::move(client);
......
...@@ -42,6 +42,7 @@ class CONTENT_EXPORT MediaSessionServiceImpl ...@@ -42,6 +42,7 @@ class CONTENT_EXPORT MediaSessionServiceImpl
} }
void DidFinishNavigation(); void DidFinishNavigation();
void FlushForTesting();
// blink::mojom::MediaSessionService implementation. // blink::mojom::MediaSessionService implementation.
void SetClient(blink::mojom::MediaSessionClientPtr client) override; void SetClient(blink::mojom::MediaSessionClientPtr client) override;
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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/mock_media_session_service_impl.h"
namespace content {
MockMediaSessionClient::MockMediaSessionClient() = default;
MockMediaSessionClient::~MockMediaSessionClient() = default;
blink::mojom::MediaSessionClientPtr
MockMediaSessionClient::CreateInterfacePtrAndBind() {
blink::mojom::MediaSessionClientPtr client;
binding_.Bind(mojo::MakeRequest(&client));
return client;
}
MockMediaSessionServiceImpl::MockMediaSessionServiceImpl(
content::RenderFrameHost* rfh)
: MediaSessionServiceImpl(rfh) {
SetClient(mock_client_.CreateInterfacePtrAndBind());
}
MockMediaSessionServiceImpl::~MockMediaSessionServiceImpl() = default;
} // namespace content
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_SERVICE_IMPL_H_
#define CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_SERVICE_IMPL_H_
#include "content/browser/media/session/media_session_service_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/platform/modules/mediasession/media_session.mojom.h"
namespace content {
class MockMediaSessionClient : public blink::mojom::MediaSessionClient {
public:
MockMediaSessionClient();
~MockMediaSessionClient() override;
blink::mojom::MediaSessionClientPtr CreateInterfacePtrAndBind();
MOCK_METHOD1(DidReceiveAction,
void(media_session::mojom::MediaSessionAction action));
private:
mojo::Binding<blink::mojom::MediaSessionClient> binding_{this};
DISALLOW_COPY_AND_ASSIGN(MockMediaSessionClient);
};
class MockMediaSessionServiceImpl : public content::MediaSessionServiceImpl {
public:
explicit MockMediaSessionServiceImpl(content::RenderFrameHost* rfh);
~MockMediaSessionServiceImpl() override;
MockMediaSessionClient& mock_client() { return mock_client_; }
private:
MockMediaSessionClient mock_client_;
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_SERVICE_IMPL_H_
...@@ -53,6 +53,8 @@ jumbo_static_library("test_support") { ...@@ -53,6 +53,8 @@ jumbo_static_library("test_support") {
"../browser/media/session/mock_media_session_observer.h", "../browser/media/session/mock_media_session_observer.h",
"../browser/media/session/mock_media_session_player_observer.cc", "../browser/media/session/mock_media_session_player_observer.cc",
"../browser/media/session/mock_media_session_player_observer.h", "../browser/media/session/mock_media_session_player_observer.h",
"../browser/media/session/mock_media_session_service_impl.cc",
"../browser/media/session/mock_media_session_service_impl.h",
"../browser/service_worker/embedded_worker_test_helper.cc", "../browser/service_worker/embedded_worker_test_helper.cc",
"../browser/service_worker/embedded_worker_test_helper.h", "../browser/service_worker/embedded_worker_test_helper.h",
"../browser/service_worker/service_worker_test_utils.cc", "../browser/service_worker/service_worker_test_utils.cc",
......
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