Bug 1413362 - part 1: Add GeckoVRManager to support GVR WebVR implementation on Android r=jchen,snorp
MozReview-Commit-ID: C7XTF8N1W9a
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -384,16 +384,17 @@ gvjar.sources += [geckoview_source_dir +
'GeckoProfile.java',
'GeckoProfileDirectories.java',
'GeckoScreenOrientation.java',
'GeckoSharedPrefs.java',
'GeckoThread.java',
'GeckoView.java',
'GeckoViewHandler.java',
'GeckoViewSettings.java',
+ 'GeckoVRManager.java',
'gfx/BitmapUtils.java',
'gfx/BufferedImage.java',
'gfx/BufferedImageGLInfo.java',
'gfx/DynamicToolbarAnimator.java',
'gfx/FloatSize.java',
'gfx/FullScreenState.java',
'gfx/GeckoLayerClient.java',
'gfx/GeckoSurface.java',
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java
@@ -0,0 +1,125 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko;
+
+import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.util.ThreadUtils;
+
+public class GeckoVRManager {
+ /**
+ * GeckoView applications implement this interface to provide GVR support for WebVR.
+ */
+ public interface GVRDelegate {
+ /**
+ * Creates non-presenting context. Will be invoked in the compositor thread.
+ */
+ long createNonPresentingContext();
+ /**
+ * Destroys non-presenting context. Will be invoked in the compositor thread.
+ */
+ void destroyNonPresentingContext();
+ /**
+ * Called when WebVR needs a presenting context. Will be invoked in the UI thread.
+ */
+ boolean enableVRMode();
+ /**
+ * Called when WebVR has finished presenting. Will be invoked in the UI thread.
+ */
+ void disableVRMode();
+ }
+
+ private static GVRDelegate mGVRDelegate;
+
+ /**
+ * Set the GVR Delegate for GeckoView.
+ * @param delegate GVRDelegate instance or null to unset.
+ */
+ public static void setGVRDelegate(GVRDelegate delegate) {
+ mGVRDelegate = delegate;
+ }
+
+ /**
+ * Set the GVR paused state.
+ * @param aPaused True if the application is being paused, False if the
+ * application is resuming.
+ */
+ @WrapForJNI(calledFrom = "ui")
+ public static native void setGVRPaused(final boolean aPaused);
+
+ /**
+ * Set the GVR presenting context.
+ * @param aContext GVR context to use when WebVR starts to present. Pass in
+ * zero to stop presenting.
+ */
+ @WrapForJNI(calledFrom = "ui")
+ public static native void setGVRPresentingContext(final long aContext);
+
+ /**
+ * Inform WebVR that the non-presenting context needs to be destroyed.
+ */
+ @WrapForJNI(calledFrom = "ui")
+ public static native void cleanupGVRNonPresentingContext();
+
+ @WrapForJNI
+ /* package */ static boolean isGVRPresent() {
+ return mGVRDelegate != null;
+ }
+
+ @WrapForJNI
+ /* package */ static long createGVRNonPresentingContext() {
+ if (mGVRDelegate == null) {
+ return 0;
+ }
+ return mGVRDelegate.createNonPresentingContext();
+ }
+
+ @WrapForJNI
+ /* package */ static void destroyGVRNonPresentingContext() {
+ if (mGVRDelegate == null) {
+ return;
+ }
+ mGVRDelegate.destroyNonPresentingContext();
+ }
+
+ @WrapForJNI
+ /* package */ static void enableVRMode() {
+ if (!ThreadUtils.isOnUiThread()) {
+ ThreadUtils.postToUiThread(new Runnable() {
+ @Override
+ public void run() {
+ enableVRMode();
+ }
+ });
+ return;
+ }
+
+ if (mGVRDelegate == null) {
+ return;
+ }
+
+ mGVRDelegate.enableVRMode();
+ }
+
+ @WrapForJNI
+ /* package */ static void disableVRMode() {
+ if (!ThreadUtils.isOnUiThread()) {
+ ThreadUtils.postToUiThread(new Runnable() {
+ @Override
+ public void run() {
+ disableVRMode();
+ }
+ });
+ return;
+ }
+
+ if (mGVRDelegate == null) {
+ return;
+ }
+
+ mGVRDelegate.disableVRMode();
+ }
+}
new file mode 100644
--- /dev/null
+++ b/widget/android/GeckoVRManager.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_GeckoVRManager_h_
+#define mozilla_GeckoVRManager_h_
+
+#include "GeneratedJNINatives.h"
+#include "mozilla/jni/Utils.h"
+
+#if defined(MOZ_ANDROID_GOOGLE_VR)
+#include "gfxVRGVRAPI.h"
+extern bool SetupGVRJNI(JNIEnv* env);
+#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+
+namespace mozilla {
+
+class GeckoVRManager
+ : public mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager>
+{
+ typedef mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager> Super;
+public:
+ static void Init()
+ {
+ Super::Init();
+#if defined(MOZ_ANDROID_GOOGLE_VR)
+ SetupGVRJNI(jni::GetGeckoThreadEnv());
+#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+ }
+
+ static void SetGVRPresentingContext(const int64_t aContext)
+ {
+#if defined(MOZ_ANDROID_GOOGLE_VR)
+ mozilla::gfx::SetGVRPresentingContext((void*)aContext);
+#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+ }
+
+ static void CleanupGVRNonPresentingContext()
+ {
+#if defined(MOZ_ANDROID_GOOGLE_VR)
+ mozilla::gfx::CleanupGVRNonPresentingContext();
+#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+ }
+
+ static void SetGVRPaused(const bool aPaused)
+ {
+#if defined(MOZ_ANDROID_GOOGLE_VR)
+ mozilla::gfx::SetGVRPaused(aPaused);
+#endif // defined(MOZ_ANDROID_GOOGLE_VR)
+ }
+
+ static void* CreateGVRNonPresentingContext()
+ {
+ return (void*)mozilla::java::GeckoVRManager::CreateGVRNonPresentingContext();
+ }
+
+ static void DestroyGVRNonPresentingContext()
+ {
+ mozilla::java::GeckoVRManager::DestroyGVRNonPresentingContext();
+ }
+
+ static void EnableVRMode()
+ {
+ mozilla::java::GeckoVRManager::EnableVRMode();
+ }
+
+ static void DisableVRMode()
+ {
+ mozilla::java::GeckoVRManager::DisableVRMode();
+ }
+
+ static bool IsGVRPresent()
+ {
+ return mozilla::java::GeckoVRManager::IsGVRPresent();
+ }
+
+};
+
+} // namespace mozilla
+
+#endif // mozilla_GeckoVRManager_h_
--- a/widget/android/GeneratedJNINatives.h
+++ b/widget/android/GeneratedJNINatives.h
@@ -253,16 +253,39 @@ const JNINativeMethod GeckoThread::Nativ
::template Wrap<&Impl::SpeculativeConnect>),
mozilla::jni::MakeNativeMethod<GeckoThread::WaitOnGecko_t>(
mozilla::jni::NativeStub<GeckoThread::WaitOnGecko_t, Impl>
::template Wrap<&Impl::WaitOnGecko>)
};
template<class Impl>
+class GeckoVRManager::Natives : public mozilla::jni::NativeImpl<GeckoVRManager, Impl>
+{
+public:
+ static const JNINativeMethod methods[3];
+};
+
+template<class Impl>
+const JNINativeMethod GeckoVRManager::Natives<Impl>::methods[] = {
+
+ mozilla::jni::MakeNativeMethod<GeckoVRManager::CleanupGVRNonPresentingContext_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::CleanupGVRNonPresentingContext_t, Impl>
+ ::template Wrap<&Impl::CleanupGVRNonPresentingContext>),
+
+ mozilla::jni::MakeNativeMethod<GeckoVRManager::SetGVRPaused_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::SetGVRPaused_t, Impl>
+ ::template Wrap<&Impl::SetGVRPaused>),
+
+ mozilla::jni::MakeNativeMethod<GeckoVRManager::SetGVRPresentingContext_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::SetGVRPresentingContext_t, Impl>
+ ::template Wrap<&Impl::SetGVRPresentingContext>)
+};
+
+template<class Impl>
class GeckoView::Window::Natives : public mozilla::jni::NativeImpl<Window, Impl>
{
public:
static const JNINativeMethod methods[4];
};
template<class Impl>
const JNINativeMethod GeckoView::Window::Natives<Impl>::methods[] = {
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -945,16 +945,68 @@ auto GeckoThread::State::RESTARTING() ->
constexpr char GeckoThread::State::RUNNING_t::name[];
constexpr char GeckoThread::State::RUNNING_t::signature[];
auto GeckoThread::State::RUNNING() -> State::LocalRef
{
return mozilla::jni::Field<RUNNING_t>::Get(State::Context(), nullptr);
}
+const char GeckoVRManager::name[] =
+ "org/mozilla/gecko/GeckoVRManager";
+
+constexpr char GeckoVRManager::CleanupGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::CleanupGVRNonPresentingContext_t::signature[];
+
+constexpr char GeckoVRManager::CreateGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::CreateGVRNonPresentingContext_t::signature[];
+
+auto GeckoVRManager::CreateGVRNonPresentingContext() -> int64_t
+{
+ return mozilla::jni::Method<CreateGVRNonPresentingContext_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::DestroyGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::DestroyGVRNonPresentingContext_t::signature[];
+
+auto GeckoVRManager::DestroyGVRNonPresentingContext() -> void
+{
+ return mozilla::jni::Method<DestroyGVRNonPresentingContext_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::DisableVRMode_t::name[];
+constexpr char GeckoVRManager::DisableVRMode_t::signature[];
+
+auto GeckoVRManager::DisableVRMode() -> void
+{
+ return mozilla::jni::Method<DisableVRMode_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::EnableVRMode_t::name[];
+constexpr char GeckoVRManager::EnableVRMode_t::signature[];
+
+auto GeckoVRManager::EnableVRMode() -> void
+{
+ return mozilla::jni::Method<EnableVRMode_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::IsGVRPresent_t::name[];
+constexpr char GeckoVRManager::IsGVRPresent_t::signature[];
+
+auto GeckoVRManager::IsGVRPresent() -> bool
+{
+ return mozilla::jni::Method<IsGVRPresent_t>::Call(GeckoVRManager::Context(), nullptr);
+}
+
+constexpr char GeckoVRManager::SetGVRPaused_t::name[];
+constexpr char GeckoVRManager::SetGVRPaused_t::signature[];
+
+constexpr char GeckoVRManager::SetGVRPresentingContext_t::name[];
+constexpr char GeckoVRManager::SetGVRPresentingContext_t::signature[];
+
const char GeckoView::name[] =
"org/mozilla/gecko/GeckoView";
const char GeckoView::State::name[] =
"org/mozilla/gecko/GeckoView$State";
constexpr char GeckoView::State::INITIAL_t::name[];
constexpr char GeckoView::State::INITIAL_t::signature[];
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -2823,16 +2823,177 @@ public:
static auto RUNNING() -> State::LocalRef;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
};
+class GeckoVRManager : public mozilla::jni::ObjectBase<GeckoVRManager>
+{
+public:
+ static const char name[];
+
+ explicit GeckoVRManager(const Context& ctx) : ObjectBase<GeckoVRManager>(ctx) {}
+
+ struct CleanupGVRNonPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "cleanupGVRNonPresentingContext";
+ static constexpr char signature[] =
+ "()V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::UI;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ struct CreateGVRNonPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef int64_t ReturnType;
+ typedef int64_t SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "createGVRNonPresentingContext";
+ static constexpr char signature[] =
+ "()J";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto CreateGVRNonPresentingContext() -> int64_t;
+
+ struct DestroyGVRNonPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "destroyGVRNonPresentingContext";
+ static constexpr char signature[] =
+ "()V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto DestroyGVRNonPresentingContext() -> void;
+
+ struct DisableVRMode_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "disableVRMode";
+ static constexpr char signature[] =
+ "()V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto DisableVRMode() -> void;
+
+ struct EnableVRMode_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "enableVRMode";
+ static constexpr char signature[] =
+ "()V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto EnableVRMode() -> void;
+
+ struct IsGVRPresent_t {
+ typedef GeckoVRManager Owner;
+ typedef bool ReturnType;
+ typedef bool SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "isGVRPresent";
+ static constexpr char signature[] =
+ "()Z";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto IsGVRPresent() -> bool;
+
+ struct SetGVRPaused_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<
+ bool> Args;
+ static constexpr char name[] = "setGVRPaused";
+ static constexpr char signature[] =
+ "(Z)V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::UI;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ struct SetGVRPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<
+ int64_t> Args;
+ static constexpr char name[] = "setGVRPresentingContext";
+ static constexpr char signature[] =
+ "(J)V";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::UI;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::ANY;
+
+ template<class Impl> class Natives;
+};
+
class GeckoView : public mozilla::jni::ObjectBase<GeckoView>
{
public:
static const char name[];
explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {}
class State;
--- a/widget/android/moz.build
+++ b/widget/android/moz.build
@@ -61,16 +61,17 @@ include('/ipc/chromium/chromium-config.m
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/docshell/base',
'/dom/base',
'/dom/system/android',
'/gfx/2d',
+ '/gfx/vr',
'/layout/painting',
'/netwerk/base',
'/netwerk/cache',
'/widget',
'/xpcom/threads',
]
CXXFLAGS += ['-Wno-error=shadow']
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -64,16 +64,17 @@
#include "AndroidAlerts.h"
#include "AndroidUiThread.h"
#include "ANRReporter.h"
#include "GeckoBatteryManager.h"
#include "GeckoNetworkManager.h"
#include "GeckoProcessManager.h"
#include "GeckoScreenOrientation.h"
+#include "GeckoVRManager.h"
#include "PrefsHelper.h"
#include "fennec/MemoryMonitor.h"
#include "fennec/Telemetry.h"
#include "fennec/ThumbnailHelper.h"
#ifdef DEBUG_ANDROID_EVENTS
#define EVLOG(args...) ALOG(args)
#else
@@ -402,16 +403,17 @@ nsAppShell::nsAppShell()
AndroidBridge::ConstructBridge();
GeckoAppShellSupport::Init();
GeckoThreadSupport::Init();
mozilla::GeckoBatteryManager::Init();
mozilla::GeckoNetworkManager::Init();
mozilla::GeckoProcessManager::Init();
mozilla::GeckoScreenOrientation::Init();
mozilla::PrefsHelper::Init();
+ mozilla::GeckoVRManager::Init();
nsWindow::InitNatives();
if (jni::IsFennec()) {
mozilla::ANRReporter::Init();
mozilla::MemoryMonitor::Init();
mozilla::widget::Telemetry::Init();
mozilla::ThumbnailHelper::Init();
}