summaryrefslogtreecommitdiff
path: root/chromium/content/browser/media/session
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/media/session')
-rw-r--r--chromium/content/browser/media/session/media_session_android.cc36
-rw-r--r--chromium/content/browser/media/session/media_session_android.h16
-rw-r--r--chromium/content/browser/media/session/media_session_impl.cc21
-rw-r--r--chromium/content/browser/media/session/media_session_impl.h8
-rw-r--r--chromium/content/browser/media/session/media_session_impl_browsertest.cc8
5 files changed, 61 insertions, 28 deletions
diff --git a/chromium/content/browser/media/session/media_session_android.cc b/chromium/content/browser/media/session/media_session_android.cc
index 0df088b19cd..87c39dfcd09 100644
--- a/chromium/content/browser/media/session/media_session_android.cc
+++ b/chromium/content/browser/media/session/media_session_android.cc
@@ -38,9 +38,14 @@ MediaSessionAndroid::MediaSessionAndroid(MediaSessionImpl* session)
Java_MediaSessionImpl_create(env, reinterpret_cast<intptr_t>(this));
j_media_session_ = JavaObjectWeakGlobalRef(env, j_media_session);
- WebContentsAndroid* contents_android = GetWebContentsAndroid();
- if (contents_android)
- contents_android->SetMediaSession(j_media_session);
+ WebContentsImpl* contents =
+ static_cast<WebContentsImpl*>(media_session_->web_contents());
+ if (contents) {
+ web_contents_android_ = contents->GetWebContentsAndroid();
+ DCHECK(web_contents_android_);
+ web_contents_android_->SetMediaSession(j_media_session);
+ web_contents_android_->AddDestructionObserver(this);
+ }
session->AddObserver(observer_receiver_.BindNewPipeAndPassRemote());
}
@@ -55,9 +60,10 @@ MediaSessionAndroid::~MediaSessionAndroid() {
j_media_session_.reset();
- WebContentsAndroid* contents_android = GetWebContentsAndroid();
- if (contents_android)
- contents_android->SetMediaSession(nullptr);
+ if (web_contents_android_) {
+ web_contents_android_->SetMediaSession(nullptr);
+ web_contents_android_->RemoveDestructionObserver(this);
+ }
}
// static
@@ -71,7 +77,7 @@ ScopedJavaLocalRef<jobject> JNI_MediaSessionImpl_GetMediaSessionFromWebContents(
MediaSessionImpl* session = MediaSessionImpl::Get(contents);
DCHECK(session);
return MediaSessionAndroid::JavaObjectGetter::GetJavaObject(
- session->session_android());
+ session->GetMediaSessionAndroid());
}
void MediaSessionAndroid::MediaSessionInfoChanged(
@@ -173,6 +179,14 @@ void MediaSessionAndroid::MediaSessionPositionChanged(
}
}
+// The Java MediaSession is kept alive by the Java WebContents and will be
+// cleared when the WebContents is destroyed, so we destroy the corresponding
+// MediaSessionAndroid to ensure mediaSessionDestroyed is called.
+void MediaSessionAndroid::WebContentsAndroidDestroyed(
+ WebContentsAndroid* web_contents_android) {
+ media_session_->ClearMediaSessionAndroid(); // Deletes |this|.
+}
+
void MediaSessionAndroid::Resume(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_obj) {
@@ -228,14 +242,6 @@ void MediaSessionAndroid::RequestSystemAudioFocus(
media_session::mojom::AudioFocusType::kGain);
}
-WebContentsAndroid* MediaSessionAndroid::GetWebContentsAndroid() {
- WebContentsImpl* contents =
- static_cast<WebContentsImpl*>(media_session_->web_contents());
- if (!contents)
- return nullptr;
- return contents->GetWebContentsAndroid();
-}
-
ScopedJavaLocalRef<jobject> MediaSessionAndroid::GetJavaObject() {
JNIEnv* env = base::android::AttachCurrentThread();
return j_media_session_.get(env);
diff --git a/chromium/content/browser/media/session/media_session_android.h b/chromium/content/browser/media/session/media_session_android.h
index 2c7c2d95f84..b7fd9bdede6 100644
--- a/chromium/content/browser/media/session/media_session_android.h
+++ b/chromium/content/browser/media/session/media_session_android.h
@@ -11,20 +11,21 @@
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
+#include "content/browser/web_contents/web_contents_android.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "services/media_session/public/mojom/media_session.mojom.h"
namespace content {
class MediaSessionImpl;
-class WebContentsAndroid;
// This class is interlayer between native MediaSession and Java
// MediaSession. This class is owned by the native MediaSession and will
// teardown Java MediaSession when the native MediaSession is destroyed.
// Java MediaSessionObservers are also proxied via this class.
class MediaSessionAndroid final
- : public media_session::mojom::MediaSessionObserver {
+ : public media_session::mojom::MediaSessionObserver,
+ public WebContentsAndroid::DestructionObserver {
public:
// Helper class for calling GetJavaObject() in a static method, in order to
// avoid leaking the Java object outside.
@@ -48,6 +49,12 @@ class MediaSessionAndroid final
void MediaSessionPositionChanged(
const base::Optional<media_session::MediaPosition>& position) override;
+ // WebContentsAndroid::DestructionObserver overrides:
+ // TODO(crbug.com/1091229): Remove this when we correctly support media
+ // sessions in portals.
+ void WebContentsAndroidDestroyed(
+ WebContentsAndroid* web_contents_android) override;
+
// MediaSession method wrappers.
void Resume(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj);
void Suspend(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj);
@@ -66,13 +73,14 @@ class MediaSessionAndroid final
const base::android::JavaParamRef<jobject>& j_obj);
private:
- WebContentsAndroid* GetWebContentsAndroid();
-
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
// The linked Java object. The strong reference is hold by Java WebContensImpl
// to avoid introducing a new GC root.
JavaObjectWeakGlobalRef j_media_session_;
+ // WebContentsAndroid corresponding to the Java WebContentsImpl that holds a
+ // strong reference to |j_media_session_|.
+ WebContentsAndroid* web_contents_android_;
MediaSessionImpl* const media_session_;
diff --git a/chromium/content/browser/media/session/media_session_impl.cc b/chromium/content/browser/media/session/media_session_impl.cc
index e26a08c2b86..a364a0497c7 100644
--- a/chromium/content/browser/media/session/media_session_impl.cc
+++ b/chromium/content/browser/media/session/media_session_impl.cc
@@ -225,6 +225,22 @@ MediaSessionImpl::~MediaSessionImpl() {
DCHECK(audio_focus_state_ == State::INACTIVE);
}
+#if defined(OS_ANDROID)
+void MediaSessionImpl::ClearMediaSessionAndroid() {
+ session_android_.reset();
+}
+
+MediaSessionAndroid* MediaSessionImpl::GetMediaSessionAndroid() {
+ // |session_android_| can be null if a portal is activated, the java
+ // WebContents is destroyed and ClearMediaSessionAndroid is called.
+ // TODO(crbug.com/1091229): Remove this when we correctly support media
+ // sessions in portals.
+ if (!session_android_)
+ session_android_ = std::make_unique<MediaSessionAndroid>(this);
+ return session_android_.get();
+}
+#endif
+
void MediaSessionImpl::WebContentsDestroyed() {
// This should only work for tests. In production, all the players should have
// already been removed before WebContents is destroyed.
@@ -280,6 +296,7 @@ void MediaSessionImpl::TitleWasSet(NavigationEntry* entry) {
}
void MediaSessionImpl::DidUpdateFaviconURL(
+ RenderFrameHost* rfh,
const std::vector<blink::mojom::FaviconURLPtr>& candidates) {
std::vector<media_session::MediaImage> icons;
@@ -831,7 +848,6 @@ MediaSessionImpl::MediaSessionImpl(WebContents* web_contents)
#if defined(OS_ANDROID)
session_android_.reset(new MediaSessionAndroid(this));
#endif // defined(OS_ANDROID)
-
if (web_contents && web_contents->GetMainFrame() &&
web_contents->GetMainFrame()->GetView()) {
focused_ = web_contents->GetMainFrame()->GetView()->HasFocus();
@@ -845,7 +861,8 @@ void MediaSessionImpl::Initialize() {
delegate_->MediaSessionInfoChanged(GetMediaSessionInfoSync());
DCHECK(web_contents());
- DidUpdateFaviconURL(web_contents()->GetFaviconURLs());
+ DidUpdateFaviconURL(web_contents()->GetMainFrame(),
+ web_contents()->GetFaviconURLs());
}
AudioFocusDelegate::AudioFocusResult MediaSessionImpl::RequestSystemAudioFocus(
diff --git a/chromium/content/browser/media/session/media_session_impl.h b/chromium/content/browser/media/session/media_session_impl.h
index 6ec74d5a2e1..a4c9bfed80a 100644
--- a/chromium/content/browser/media/session/media_session_impl.h
+++ b/chromium/content/browser/media/session/media_session_impl.h
@@ -85,11 +85,8 @@ class MediaSessionImpl : public MediaSession,
~MediaSessionImpl() override;
#if defined(OS_ANDROID)
- static MediaSession* FromJavaMediaSession(
- const base::android::JavaRef<jobject>& j_media_session);
- MediaSessionAndroid* session_android() const {
- return session_android_.get();
- }
+ void ClearMediaSessionAndroid();
+ MediaSessionAndroid* GetMediaSessionAndroid();
#endif // defined(OS_ANDROID)
void NotifyMediaSessionMetadataChange();
@@ -139,6 +136,7 @@ class MediaSessionImpl : public MediaSession,
void OnWebContentsLostFocus(RenderWidgetHost*) override;
void TitleWasSet(NavigationEntry* entry) override;
void DidUpdateFaviconURL(
+ RenderFrameHost* rfh,
const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
diff --git a/chromium/content/browser/media/session/media_session_impl_browsertest.cc b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
index 77161c71d44..255ea2f601e 100644
--- a/chromium/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
@@ -2514,7 +2514,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UpdateFaviconURL) {
GURL("https://www.example.org/favicon6.png"),
blink::mojom::FaviconIconType::kTouchIcon, std::vector<gfx::Size>()));
- media_session_->DidUpdateFaviconURL(favicons);
+ media_session_->DidUpdateFaviconURL(shell()->web_contents()->GetMainFrame(),
+ favicons);
{
std::vector<media_session::MediaImage> expected_images;
@@ -2542,6 +2543,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UpdateFaviconURL) {
{
media_session::test::MockMediaSessionMojoObserver observer(*media_session_);
media_session_->DidUpdateFaviconURL(
+ shell()->web_contents()->GetMainFrame(),
std::vector<blink::mojom::FaviconURLPtr>());
observer.WaitForExpectedImagesOfType(
media_session::mojom::MediaSessionImageType::kSourceIcon,
@@ -2556,7 +2558,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
GURL("https://www.example.org/favicon1.png"),
blink::mojom::FaviconIconType::kFavicon, std::vector<gfx::Size>()));
- media_session_->DidUpdateFaviconURL(favicons);
+ media_session_->DidUpdateFaviconURL(shell()->web_contents()->GetMainFrame(),
+ favicons);
{
std::vector<media_session::MediaImage> expected_images;
@@ -2607,6 +2610,7 @@ class FaviconWaiter : public WebContentsObserver {
: WebContentsObserver(web_contents) {}
void DidUpdateFaviconURL(
+ RenderFrameHost* render_frame_host,
const std::vector<blink::mojom::FaviconURLPtr>& candidates) override {
received_favicon_ = true;
run_loop_.Quit();