Bug 1413362 - part 1: Add GeckoVRManager to support GVR WebVR implementation on Android
MozReview-Commit-ID: C7XTF8N1W9a
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -385,16 +385,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,137 @@
+/* -*- 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 createGVRNonPresentingContext();
+ /**
+ * Destroys non-presenting context. Will be invoked in the compositor thread.
+ */
+ void destroyGVRNonPresentingContext();
+ /**
+ * 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.
+ */
+ public static void setGVRPaused(final boolean aPaused) {
+ nativeSetGVRPaused(aPaused);
+ }
+
+ /**
+ * Set the GVR presenting context.
+ * @param aContext GVR context to use when WebVR starts to present. Pass in
+ * zero to stop presenting.
+ */
+ public static void setGVRPresentingContext(final long aContext) {
+ nativeSetGVRPresentingContext(aContext);
+ }
+
+ /**
+ * Inform WebVR that the non-presenting context needs to be destroyed.
+ */
+ public static void cleanupGVRNonPresentingContext() {
+ nativeCleanupGVRNonPresentingContext();
+ }
+
+ @WrapForJNI
+ private static boolean isGVRPresent() {
+ return mGVRDelegate != null;
+ }
+
+ @WrapForJNI
+ private static long createGVRNonPresentingContext() {
+ if (mGVRDelegate == null) {
+ return 0;
+ }
+ return mGVRDelegate.createGVRNonPresentingContext();
+ }
+
+ @WrapForJNI
+ private static void destroyGVRNonPresentingContext() {
+ if (mGVRDelegate == null) {
+ return;
+ }
+ mGVRDelegate.destroyGVRNonPresentingContext();
+ }
+
+ @WrapForJNI
+ private static void enableVRMode() {
+ if (!ThreadUtils.isOnUiThread()) {
+ ThreadUtils.postToUiThread(new Runnable() {
+ @Override
+ public void run() {
+ enableVRMode();
+ }
+ });
+ return;
+ }
+
+ if (mGVRDelegate == null) {
+ return;
+ }
+
+ mGVRDelegate.enableVRMode();
+ }
+
+ @WrapForJNI
+ private static void disableVRMode() {
+ if (!ThreadUtils.isOnUiThread()) {
+ ThreadUtils.postToUiThread(new Runnable() {
+ @Override
+ public void run() {
+ disableVRMode();
+ }
+ });
+ return;
+ }
+
+ if (mGVRDelegate == null) {
+ return;
+ }
+
+ mGVRDelegate.disableVRMode();
+ }
+
+ @WrapForJNI(calledFrom = "ui")
+ static native void nativeSetGVRPresentingContext(final long aContext);
+
+ @WrapForJNI(calledFrom = "ui")
+ static native void nativeCleanupGVRNonPresentingContext();
+
+ @WrapForJNI(calledFrom = "ui")
+ static native void nativeSetGVRPaused(final boolean paused);
+}
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -55,16 +55,20 @@
#include "FennecJNIWrappers.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::jni;
using namespace mozilla::java;
+#if defined(MOZ_USE_GVR_ANDROID)
+extern bool SetupGVRJNI(JNIEnv* env);
+#endif // MOZ_USE_GVR_ANDROID
+
AndroidBridge* AndroidBridge::sBridge = nullptr;
static jobject sGlobalContext = nullptr;
nsDataHashtable<nsStringHashKey, nsString> AndroidBridge::sStoragePaths;
jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass,
const char* methodName, const char* methodType)
{
jmethodID methodID = env->GetMethodID(jClass, methodName, methodType);
@@ -181,16 +185,20 @@ AndroidBridge::AndroidBridge()
AutoJNIClass readableByteChannel(jEnv, "java/nio/channels/ReadableByteChannel");
jReadableByteChannel = readableByteChannel.getGlobalRef();
jByteBufferRead = readableByteChannel.getMethod("read", "(Ljava/nio/ByteBuffer;)I");
AutoJNIClass inputStream(jEnv, "java/io/InputStream");
jInputStream = inputStream.getGlobalRef();
jClose = inputStream.getMethod("close", "()V");
jAvailable = inputStream.getMethod("available", "()I");
+
+#if defined(MOZ_USE_GVR_ANDROID)
+ SetupGVRJNI(jEnv);
+#endif // MOZ_USE_GVR_ANDROID
}
// Raw JNIEnv variants.
jstring AndroidBridge::NewJavaString(JNIEnv* env, const char16_t* string, uint32_t len) {
jstring ret = env->NewString(reinterpret_cast<const jchar*>(string), len);
if (env->ExceptionCheck()) {
ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__);
env->ExceptionDescribe();
new file mode 100644
--- /dev/null
+++ b/widget/android/GeckoVRManager.cpp
@@ -0,0 +1,63 @@
+#include "GeckoVRManager.h"
+
+#if defined(MOZ_USE_GVR_ANDROID)
+#include "gfxVRGVRAPI.h"
+#endif // defined(MOZ_USE_GVR_ANDROID)
+
+namespace mozilla {
+
+void
+GeckoVRManager::NativeSetGVRPresentingContext(const int64_t aContext)
+{
+#if defined(MOZ_USE_GVR_ANDROID)
+ mozilla::gfx::SetGVRPresentingContext((void*)aContext);
+#endif // defined(MOZ_USE_GVR_ANDROID)
+}
+
+void
+GeckoVRManager::NativeCleanupGVRNonPresentingContext()
+{
+#if defined(MOZ_USE_GVR_ANDROID)
+ mozilla::gfx::CleanupGVRNonPresentingContext();
+#endif // defined(MOZ_USE_GVR_ANDROID)
+}
+
+void
+GeckoVRManager::NativeSetGVRPaused(const bool aPaused)
+{
+#if defined(MOZ_USE_GVR_ANDROID)
+ mozilla::gfx::SetGVRPaused(aPaused);
+#endif // defined(MOZ_USE_GVR_ANDROID)
+}
+
+void*
+GeckoVRManager::CreateGVRNonPresentingContext()
+{
+ return (void*)mozilla::java::GeckoVRManager::CreateGVRNonPresentingContext();
+}
+
+void
+GeckoVRManager::DestroyGVRNonPresentingContext()
+{
+ mozilla::java::GeckoVRManager::DestroyGVRNonPresentingContext();
+}
+
+void
+GeckoVRManager::EnableVRMode()
+{
+ mozilla::java::GeckoVRManager::EnableVRMode();
+}
+
+void
+GeckoVRManager::DisableVRMode()
+{
+ mozilla::java::GeckoVRManager::DisableVRMode();
+}
+
+bool
+GeckoVRManager::IsGVRPresent()
+{
+ return mozilla::java::GeckoVRManager::IsGVRPresent();
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/android/GeckoVRManager.h
@@ -0,0 +1,25 @@
+#ifndef GeckoVRManager_h_
+#define GeckoVRManager_h_
+
+#include "GeneratedJNINatives.h"
+
+namespace mozilla {
+
+class GeckoVRManager
+ : public mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager>
+{
+
+public:
+ static void NativeSetGVRPresentingContext(const int64_t aContext);
+ static void NativeCleanupGVRNonPresentingContext();
+ static void NativeSetGVRPaused(const bool aPaused);
+ static void* CreateGVRNonPresentingContext();
+ static void DestroyGVRNonPresentingContext();
+ static void EnableVRMode();
+ static void DisableVRMode();
+ static bool IsGVRPresent();
+};
+
+} // namespace mozilla
+
+#endif // 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::NativeCleanupGVRNonPresentingContext_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::NativeCleanupGVRNonPresentingContext_t, Impl>
+ ::template Wrap<&Impl::NativeCleanupGVRNonPresentingContext>),
+
+ mozilla::jni::MakeNativeMethod<GeckoVRManager::NativeSetGVRPaused_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::NativeSetGVRPaused_t, Impl>
+ ::template Wrap<&Impl::NativeSetGVRPaused>),
+
+ mozilla::jni::MakeNativeMethod<GeckoVRManager::NativeSetGVRPresentingContext_t>(
+ mozilla::jni::NativeStub<GeckoVRManager::NativeSetGVRPresentingContext_t, Impl>
+ ::template Wrap<&Impl::NativeSetGVRPresentingContext>)
+};
+
+template<class Impl>
class GeckoView::Window::Natives : public mozilla::jni::NativeImpl<Window, Impl>
{
public:
static const JNINativeMethod methods[5];
};
template<class Impl>
const JNINativeMethod GeckoView::Window::Natives<Impl>::methods[] = {
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -910,16 +910,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::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::NativeCleanupGVRNonPresentingContext_t::name[];
+constexpr char GeckoVRManager::NativeCleanupGVRNonPresentingContext_t::signature[];
+
+constexpr char GeckoVRManager::NativeSetGVRPaused_t::name[];
+constexpr char GeckoVRManager::NativeSetGVRPaused_t::signature[];
+
+constexpr char GeckoVRManager::NativeSetGVRPresentingContext_t::name[];
+constexpr char GeckoVRManager::NativeSetGVRPresentingContext_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
@@ -2728,16 +2728,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 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 NativeCleanupGVRNonPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<> Args;
+ static constexpr char name[] = "nativeCleanupGVRNonPresentingContext";
+ 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 NativeSetGVRPaused_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<
+ bool> Args;
+ static constexpr char name[] = "nativeSetGVRPaused";
+ 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 NativeSetGVRPresentingContext_t {
+ typedef GeckoVRManager Owner;
+ typedef void ReturnType;
+ typedef void SetterType;
+ typedef mozilla::jni::Args<
+ int64_t> Args;
+ static constexpr char name[] = "nativeSetGVRPresentingContext";
+ 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
@@ -42,16 +42,17 @@ UNIFIED_SOURCES += [
'AndroidContentController.cpp',
'AndroidJavaWrappers.cpp',
'AndroidJNI.cpp',
'AndroidJNIWrapper.cpp',
'AndroidUiThread.cpp',
'ANRReporter.cpp',
'EventDispatcher.cpp',
'GeckoEditableSupport.cpp',
+ 'GeckoVRManager.cpp',
'GeneratedJNIWrappers.cpp',
'GfxInfo.cpp',
'nsAndroidProtocolHandler.cpp',
'nsAppShell.cpp',
'nsClipboard.cpp',
'nsDeviceContextAndroid.cpp',
'nsIdleServiceAndroid.cpp',
'nsLookAndFeel.cpp',
@@ -66,16 +67,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();
}