зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1294479 - Add native methods in PresentationMediaPlayerManager; r=snorp
Put presentation surface native methods in PMPM Instead of in GeckoAppShell, and also make these methods work with multiple GeckoViews by having them take a GeckoView parameter if necessary. This also lets us eliminate the static nsWindow reference in nsWindow.cpp.
This commit is contained in:
Родитель
6db3f09efd
Коммит
a13d864c61
|
@ -12,6 +12,7 @@ import android.os.Bundle;
|
|||
import android.support.v7.media.MediaRouter;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -19,6 +20,8 @@ import android.view.WindowManager;
|
|||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
|
||||
/**
|
||||
* A MediaPlayerManager with API 17+ Presentation support.
|
||||
*/
|
||||
|
@ -61,7 +64,8 @@ public class PresentationMediaPlayerManager extends MediaPlayerManager {
|
|||
}
|
||||
|
||||
if (presentation == null) {
|
||||
presentation = new GeckoPresentation(getActivity(), display);
|
||||
final GeckoView geckoView = (GeckoView) getActivity().findViewById(R.id.layer_view);
|
||||
presentation = new GeckoPresentation(getActivity(), display, geckoView);
|
||||
|
||||
try {
|
||||
presentation.show();
|
||||
|
@ -77,10 +81,23 @@ public class PresentationMediaPlayerManager extends MediaPlayerManager {
|
|||
}
|
||||
}
|
||||
|
||||
private final static class GeckoPresentation extends Presentation {
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
/* protected */ static native void invalidateAndScheduleComposite(GeckoView geckoView);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
/* protected */ static native void addPresentationSurface(GeckoView geckoView, Surface surface);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
/* protected */ static native void removePresentationSurface();
|
||||
|
||||
private static final class GeckoPresentation extends Presentation {
|
||||
private SurfaceView mView;
|
||||
public GeckoPresentation(Context context, Display display) {
|
||||
private GeckoView mGeckoView;
|
||||
|
||||
public GeckoPresentation(Context context, Display display, GeckoView geckoView) {
|
||||
super(context, display);
|
||||
|
||||
mGeckoView = geckoView;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,27 +108,32 @@ public class PresentationMediaPlayerManager extends MediaPlayerManager {
|
|||
setContentView(mView, new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
mView.getHolder().addCallback(new SurfaceListener());
|
||||
mView.getHolder().addCallback(new SurfaceListener(mGeckoView));
|
||||
}
|
||||
}
|
||||
|
||||
private static class SurfaceListener implements SurfaceHolder.Callback {
|
||||
private static final class SurfaceListener implements SurfaceHolder.Callback {
|
||||
private GeckoView mGeckoView;
|
||||
|
||||
public SurfaceListener(GeckoView geckoView) {
|
||||
mGeckoView = geckoView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
||||
int height) {
|
||||
// Surface changed so force a composite
|
||||
GeckoAppShell.invalidateAndScheduleComposite();
|
||||
invalidateAndScheduleComposite(mGeckoView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
GeckoAppShell.addPresentationSurface(holder.getSurface());
|
||||
GeckoAppShell.invalidateAndScheduleComposite();
|
||||
addPresentationSurface(mGeckoView, holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
GeckoAppShell.removePresentationSurface(holder.getSurface());
|
||||
removePresentationSurface();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,11 +246,6 @@ public class GeckoAppShell
|
|||
@WrapForJNI(dispatchTo = "gecko")
|
||||
public static native void notifyUriVisited(String uri);
|
||||
|
||||
public static native void invalidateAndScheduleComposite();
|
||||
|
||||
public static native void addPresentationSurface(Surface surface);
|
||||
public static native void removePresentationSurface(Surface surface);
|
||||
|
||||
private static LayerView sLayerView;
|
||||
private static Rect sScreenSize;
|
||||
|
||||
|
|
|
@ -75,9 +75,9 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
|
||||
/* This is written by the compositor thread (while the UI thread
|
||||
* is blocked on it) and read by the UI thread. */
|
||||
@WrapForJNI(stubName = "CompositorCreated", calledFrom = "ui")
|
||||
private volatile boolean mCompositorCreated;
|
||||
|
||||
|
||||
private class Compositor extends JNIObject {
|
||||
public Compositor() {
|
||||
}
|
||||
|
@ -488,6 +488,7 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
protected Object getCompositor() {
|
||||
return mCompositor;
|
||||
}
|
||||
|
|
|
@ -43,33 +43,6 @@ extern "C" {
|
|||
/*
|
||||
* Incoming JNI methods
|
||||
*/
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_invalidateAndScheduleComposite(JNIEnv*, jclass)
|
||||
{
|
||||
nsWindow::InvalidateAndScheduleComposite();
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_addPresentationSurface(JNIEnv* jenv, jclass, jobject surface)
|
||||
{
|
||||
if (surface != NULL) {
|
||||
void* window = AndroidBridge::Bridge()->AcquireNativeWindow(jenv, surface);
|
||||
if (window) {
|
||||
AndroidBridge::Bridge()->SetPresentationWindow(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_removePresentationSurface(JNIEnv* jenv, jclass, jobject surface)
|
||||
{
|
||||
void* window = AndroidBridge::Bridge()->GetPresentationWindow();
|
||||
if (window) {
|
||||
AndroidBridge::Bridge()->SetPresentationWindow(nullptr);
|
||||
AndroidBridge::Bridge()->ReleaseNativeWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_onSurfaceTextureFrameAvailable(JNIEnv* jenv, jclass, jobject surfaceTexture, jint id)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <android/log.h>
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -1036,6 +1038,12 @@ public:
|
|||
mozilla::Move(aCall)));
|
||||
}
|
||||
|
||||
static LayerViewSupport*
|
||||
FromNative(const LayerView::Compositor::LocalRef& instance)
|
||||
{
|
||||
return GetNative(instance);
|
||||
}
|
||||
|
||||
LayerViewSupport(NativePtr<LayerViewSupport>* aPtr, nsWindow* aWindow,
|
||||
const LayerView::Compositor::LocalRef& aInstance)
|
||||
: mWindow(aPtr, aWindow)
|
||||
|
@ -1210,6 +1218,92 @@ public:
|
|||
template<> const char
|
||||
nsWindow::NativePtr<nsWindow::LayerViewSupport>::sName[] = "LayerViewSupport";
|
||||
|
||||
/* PresentationMediaPlayerManager native calls access inner nsWindow functionality so PMPMSupport is a child class of nsWindow */
|
||||
class nsWindow::PMPMSupport final
|
||||
: public PresentationMediaPlayerManager::Natives<PMPMSupport>
|
||||
{
|
||||
PMPMSupport() = delete;
|
||||
|
||||
static LayerViewSupport* GetLayerViewSupport(jni::Object::Param aView)
|
||||
{
|
||||
const auto& layerView = LayerView::Ref::From(aView);
|
||||
|
||||
LayerView::Compositor::LocalRef compositor = layerView->GetCompositor();
|
||||
if (!layerView->CompositorCreated() || !compositor) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LayerViewSupport* const lvs = LayerViewSupport::FromNative(compositor);
|
||||
if (!lvs) {
|
||||
// There is a pending exception whenever FromNative returns nullptr.
|
||||
compositor.Env()->ExceptionClear();
|
||||
}
|
||||
return lvs;
|
||||
}
|
||||
|
||||
public:
|
||||
static ANativeWindow* sWindow;
|
||||
static EGLSurface sSurface;
|
||||
|
||||
static void InvalidateAndScheduleComposite(jni::Object::Param aView)
|
||||
{
|
||||
LayerViewSupport* const lvs = GetLayerViewSupport(aView);
|
||||
if (lvs) {
|
||||
lvs->SyncInvalidateAndScheduleComposite();
|
||||
}
|
||||
}
|
||||
|
||||
static void AddPresentationSurface(const jni::Class::LocalRef& aCls,
|
||||
jni::Object::Param aView,
|
||||
jni::Object::Param aSurface)
|
||||
{
|
||||
RemovePresentationSurface();
|
||||
|
||||
LayerViewSupport* const lvs = GetLayerViewSupport(aView);
|
||||
if (!lvs) {
|
||||
return;
|
||||
}
|
||||
|
||||
ANativeWindow* const window = ANativeWindow_fromSurface(
|
||||
aCls.Env(), aSurface.Get());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
sWindow = window;
|
||||
|
||||
const bool wasAlreadyPaused = lvs->CompositorPaused();
|
||||
if (!wasAlreadyPaused) {
|
||||
lvs->SyncPauseCompositor();
|
||||
}
|
||||
|
||||
if (sSurface) {
|
||||
// Destroy the EGL surface! The compositor is paused so it should
|
||||
// be okay to destroy the surface here.
|
||||
mozilla::gl::GLContextProvider::DestroyEGLSurface(sSurface);
|
||||
sSurface = nullptr;
|
||||
}
|
||||
|
||||
if (!wasAlreadyPaused) {
|
||||
lvs->SyncResumeCompositor();
|
||||
}
|
||||
|
||||
lvs->SyncInvalidateAndScheduleComposite();
|
||||
}
|
||||
|
||||
static void RemovePresentationSurface()
|
||||
{
|
||||
if (sWindow) {
|
||||
ANativeWindow_release(sWindow);
|
||||
sWindow = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ANativeWindow* nsWindow::PMPMSupport::sWindow;
|
||||
EGLSurface nsWindow::PMPMSupport::sSurface;
|
||||
|
||||
|
||||
nsWindow::GeckoViewSupport::~GeckoViewSupport()
|
||||
{
|
||||
// Disassociate our GeckoEditable instance with our native object.
|
||||
|
@ -1379,6 +1473,7 @@ nsWindow::InitNatives()
|
|||
nsWindow::GeckoViewSupport::EditableBase::Init();
|
||||
nsWindow::LayerViewSupport::Init();
|
||||
nsWindow::NPZCSupport::Init();
|
||||
nsWindow::PMPMSupport::Init();
|
||||
}
|
||||
|
||||
nsWindow*
|
||||
|
|
|
@ -109,6 +109,9 @@ private:
|
|||
// keep it last in the list, so its destructor is called first.
|
||||
mozilla::UniquePtr<GeckoViewSupport> mGeckoViewSupport;
|
||||
|
||||
// Class that implements native PresentationMediaPlayerManager calls.
|
||||
class PMPMSupport;
|
||||
|
||||
public:
|
||||
static nsWindow* TopWindow();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче