From fd928bd229c14f0e035cf4917afb69bce2fe3541 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Mon, 21 Sep 2020 21:49:02 +0000 Subject: [PATCH] Bug 1651705: Part 7 - Update MediaSessionSupport to work with NativeWeakPtr; r=geckoview-reviewers,agi This patch is similar to part 4 but for MediaSessionSupport. Conversions over to `NativeWeakPtr` are pretty straight forward thanks to the type system. Basically we take a `NativeWeakPtr`, call `Access()` on it, and if the accessor is truthy, then we call whatever methods we need to call. Creation of new pointers is done using `NativeWeakPtrHolder::Attach()` and detaching of strong references is done by `NativeWeakPtr::Detach()`. Differential Revision: https://phabricator.services.mozilla.com/D88088 --- widget/android/GeckoViewSupport.h | 8 ++++ widget/android/nsWindow.cpp | 69 +++++++++++++++++++++++-------- widget/android/nsWindow.h | 5 ++- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/widget/android/GeckoViewSupport.h b/widget/android/GeckoViewSupport.h index 0ba0b8aba3e8..a57dfe1ea13c 100644 --- a/widget/android/GeckoViewSupport.h +++ b/widget/android/GeckoViewSupport.h @@ -89,6 +89,14 @@ class GeckoViewSupport final void PassExternalResponse(java::WebResponse::Param aResponse); + void AttachMediaSessionController( + const java::GeckoSession::Window::LocalRef& inst, + jni::Object::Param aController, const int64_t aId); + + void DetachMediaSessionController( + const java::GeckoSession::Window::LocalRef& inst, + jni::Object::Param aController); + void OnWeakNonIntrusiveDetach(already_AddRefed aDisposer) { RefPtr disposer(aDisposer); disposer->Run(); diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index e676d72c462a..7e441c716280 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -175,15 +175,14 @@ namespace widget { using WindowPtr = jni::NativeWeakPtr; -class nsWindow::MediaSessionSupport final +class MediaSessionSupport final : public mozilla::java::MediaSession::Controller::Natives< MediaSessionSupport> { - using LockedWindowPtr = WindowPtr::Locked; using MediaKeysArray = nsTArray; typedef RefPtr ControllerPtr; - WindowPtr mWindow; + WindowPtr mWindow; mozilla::java::MediaSession::Controller::WeakRef mJavaController; ControllerPtr mMediaController; MediaEventListener mMetadataChangedListener; @@ -196,18 +195,30 @@ class nsWindow::MediaSessionSupport final using Base::DisposeNative; MediaSessionSupport( - NativePtr* aPtr, nsWindow* aWindow, + WindowPtr aWindow, const java::MediaSession::Controller::LocalRef& aController) - : mWindow(aPtr, aWindow), + : mWindow(aWindow), mJavaController(aController), mMediaController(nullptr) { - MOZ_ASSERT(mWindow); +#if defined(DEBUG) + auto win(mWindow.Access()); + MOZ_ASSERT(!!win); +#endif // defined(DEBUG) } bool Dispatch(const char16_t aType[], java::GeckoBundle::Param aBundle = nullptr) { - widget::EventDispatcher* dispatcher = mWindow->GetEventDispatcher(); + auto win = mWindow.Access(); + if (!win) { + return false; + } + nsWindow* gkWindow = win->GetNsWindow(); + if (!gkWindow) { + return false; + } + + widget::EventDispatcher* dispatcher = gkWindow->GetEventDispatcher(); if (!dispatcher) { return false; } @@ -335,7 +346,7 @@ class nsWindow::MediaSessionSupport final } } - void OnDetach(already_AddRefed aDisposer) { + void OnWeakNonIntrusiveDetach(already_AddRefed aDisposer) { MOZ_ASSERT(NS_IsMainThread()); RefPtr disposer = aDisposer; @@ -513,10 +524,6 @@ class nsWindow::MediaSessionSupport final } }; -template <> -const char nsWindow::NativePtr::sName[] = - "MediaSessionSupport"; - /** * PanZoomController handles its native calls on the UI thread, so make * it separate from GeckoViewSupport. @@ -1557,11 +1564,6 @@ GeckoViewSupport::~GeckoViewSupport() { if (mWindow) { mWindow->DetachNatives(); } - - if (window.mMediaSessionSupport) { - window.mMediaSessionSupport.Detach( - window.mMediaSessionSupport->GetJavaController()); - } } /* static */ @@ -1771,6 +1773,36 @@ void GeckoViewSupport::PassExternalResponse( response] { window->PassExternalWebResponse(response); }); } +void GeckoViewSupport::AttachMediaSessionController( + const GeckoSession::Window::LocalRef& inst, jni::Object::Param aController, + const int64_t aId) { + auto controller = java::MediaSession::Controller::LocalRef( + jni::GetGeckoThreadEnv(), + java::MediaSession::Controller::Ref::From(aController)); + mWindow->mMediaSessionSupport = + jni::NativeWeakPtrHolder::Attach( + controller, mWindow->mGeckoViewSupport, controller); + + RefPtr bc = BrowsingContext::Get(aId); + RefPtr nativeController = + bc->Canonical()->GetMediaController(); + MOZ_ASSERT(nativeController); + + if (auto acc = mWindow->mMediaSessionSupport.Access()) { + acc->SetNativeController(nativeController); + } + + DispatchToUiThread("GeckoViewSupport::AttachMediaSessionController", + [controller = java::MediaSession::Controller::GlobalRef( + controller)] { controller->OnAttached(); }); +} + +void GeckoViewSupport::DetachMediaSessionController( + const GeckoSession::Window::LocalRef& inst, + jni::Object::Param aController) { + mWindow->mMediaSessionSupport.Detach(); +} + } // namespace widget } // namespace mozilla @@ -1778,8 +1810,8 @@ void nsWindow::InitNatives() { jni::InitConversionStatics(); mozilla::widget::GeckoViewSupport::Base::Init(); mozilla::widget::LayerViewSupport::Init(); + mozilla::widget::MediaSessionSupport::Init(); mozilla::widget::NPZCSupport::Init(); - nsWindow::MediaSessionSupport::Init(); mozilla::widget::GeckoEditableSupport::Init(); a11y::SessionAccessibility::Init(); @@ -1791,6 +1823,7 @@ void nsWindow::DetachNatives() { mNPZCSupport.Detach(); mLayerViewSupport.Detach(); mSessionAccessibility.Detach(); + mMediaSessionSupport.Detach(); } /* static */ diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index a87c71afacd9..37818c90899f 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -38,6 +38,7 @@ class AndroidView; class GeckoEditableSupport; class GeckoViewSupport; class LayerViewSupport; +class MediaSessionSupport; class NPZCSupport; } // namespace widget @@ -95,8 +96,8 @@ class nsWindow final : public nsBaseWidget { mozilla::jni::NativeWeakPtr mSessionAccessibility; - class MediaSessionSupport; - NativePtr mMediaSessionSupport; + mozilla::jni::NativeWeakPtr + mMediaSessionSupport; // Object that implements native GeckoView calls and associated states. // nullptr for nsWindows that were not opened from GeckoView.