Skip to content

Commit

Permalink
Lazily initialize GeckoWebExecutor (#3653)
Browse files Browse the repository at this point in the history
* Lazily initialize GeckoWebExecutor
Fixes #3652 Fixes #3651

* Add extra workaround for the GeckoResult initialization problem

Co-authored-by: Randall E. Barker <simstorm@mac.com>
  • Loading branch information
MortimerGoro and bluemarvin committed Jul 8, 2020
1 parent e9c03ea commit e4f476e
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 5 deletions.
Expand Up @@ -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;

Expand Down Expand Up @@ -53,12 +54,19 @@ 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();

SessionStore.prefOverrides(this);
TelemetryWrapper.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
GleanMetricsService.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
}

protected void onActivityCreate(@NonNull Context activityContext) {
EngineProvider.INSTANCE.getDefaultGeckoWebExecutor(activityContext);
mPlaces = new Places(this);
mServices = new Services(this, mPlaces);
mAccounts = new Accounts(this);
Expand Down
Expand Up @@ -63,20 +63,24 @@ object EngineProvider {
return runtime != null
}

fun createGeckoWebExecutor(context: Context): GeckoWebExecutor {
private fun createGeckoWebExecutor(context: Context): GeckoWebExecutor {
return GeckoWebExecutor(getOrCreateRuntime(context))
}

fun getDefaultGeckoWebExecutor(context: Context): GeckoWebExecutor {
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 {
Expand Down
Expand Up @@ -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
Expand All @@ -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()
Expand Down

0 comments on commit e4f476e

Please sign in to comment.