From 175ae348b0d54c5355dee27485f0c553d7bc6264 Mon Sep 17 00:00:00 2001 From: Imanol Fernandez Date: Wed, 8 Jul 2020 13:37:25 +0200 Subject: [PATCH 1/2] Lazily initialize GeckoWebExecutor Fixes #3652 Fixes #3651 --- .../org/mozilla/vrbrowser/VRBrowserApplication.java | 1 + .../mozilla/vrbrowser/browser/engine/EngineProvider.kt | 8 ++++++-- .../vrbrowser/browser/engine/GeckoViewFetchClient.kt | 7 +++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java index 51357302b..f6480d8e1 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java @@ -57,6 +57,7 @@ public void onCreate() { } protected void onActivityCreate(@NonNull Context activityContext) { + EngineProvider.INSTANCE.getDefaultGeckoWebExecutor(activityContext); mPlaces = new Places(this); mServices = new Services(this, mPlaces); mAccounts = new Accounts(this); diff --git a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/EngineProvider.kt b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/EngineProvider.kt index 14304c528..f194cf637 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/EngineProvider.kt +++ b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/EngineProvider.kt @@ -58,20 +58,24 @@ object EngineProvider { return runtime!! } - fun createGeckoWebExecutor(context: Context): GeckoWebExecutor { + private fun createGeckoWebExecutor(context: Context): GeckoWebExecutor { return GeckoWebExecutor(getOrCreateRuntime(context)) } fun getDefaultGeckoWebExecutor(context: Context): GeckoWebExecutor { if (executor == null) { executor = createGeckoWebExecutor(context) + client?.let { it.executor = executor } + } return executor!! } fun createClient(context: Context): GeckoViewFetchClient { - return GeckoViewFetchClient(context) + val client = GeckoViewFetchClient(context) + client.executor = executor + return client } fun getDefaultClient(context: Context): GeckoViewFetchClient { diff --git a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/GeckoViewFetchClient.kt b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/GeckoViewFetchClient.kt index f69409ffc..8ad095e66 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/GeckoViewFetchClient.kt +++ b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/GeckoViewFetchClient.kt @@ -28,10 +28,13 @@ class GeckoViewFetchClient( ) : Client() { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal var executor: GeckoWebExecutor = EngineProvider.createGeckoWebExecutor(context) + internal var executor: GeckoWebExecutor? = null @Throws(IOException::class) override fun fetch(request: Request): Response { + if (executor == null) { + throw IOException("GeckoWebExecutor not initialized") + } val webRequest = request.toWebRequest(defaultHeaders) val readTimeOut = request.readTimeout ?: maxReadTimeOut @@ -47,7 +50,7 @@ class GeckoViewFetchClient( if (request.redirect == Request.Redirect.MANUAL) { fetchFlags += GeckoWebExecutor.FETCH_FLAGS_NO_REDIRECTS } - val webResponse = executor.fetch(webRequest, fetchFlags).poll(readTimeOutMillis) + val webResponse = executor!!.fetch(webRequest, fetchFlags).poll(readTimeOutMillis) webResponse?.toResponse() ?: throw IOException("Fetch failed with null response") } catch (e: TimeoutException) { throw SocketTimeoutException() From 3084eb1b218a487de854a7bd53c7b8b9e7c07fc1 Mon Sep 17 00:00:00 2001 From: Imanol Fernandez Date: Wed, 8 Jul 2020 20:16:28 +0200 Subject: [PATCH 2/2] Add extra workaround for the GeckoResult initialization problem --- .../shared/org/mozilla/vrbrowser/VRBrowserApplication.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java index f6480d8e1..66e8e4ef8 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java @@ -8,6 +8,7 @@ import android.app.Application; import android.content.Context; import android.content.res.Configuration; +import android.os.Looper; import androidx.annotation.NonNull; @@ -52,6 +53,12 @@ public void onCreate() { return; } + // Fix potential Gecko static initialization order. + // GeckoResult.ALLOW and GeckoResult.DENY static initializer might get a null mDispatcher + // depending on how JVM classloader does the initialization job. + // See https://github.com/MozillaReality/FirefoxReality/issues/3651 + Looper.getMainLooper().getThread(); + TelemetryWrapper.init(this, EngineProvider.INSTANCE.getDefaultClient(this)); GleanMetricsService.init(this, EngineProvider.INSTANCE.getDefaultClient(this)); }