Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
(Merge day) browser-engine-gecko-beta (67) -> browser-engine-gecko-re…
Browse files Browse the repository at this point in the history
…lease (67).
  • Loading branch information
pocmo committed May 22, 2019
1 parent 89800e4 commit ce15999
Show file tree
Hide file tree
Showing 19 changed files with 957 additions and 85 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/java/Gecko.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal object GeckoVersions {
/**
* GeckoView Release Version.
*/
const val release_version = "66.0.20190322021635"
const val release_version = "67.0.20190521210220"
}

@Suppress("MaxLineLength")
Expand Down
1 change: 1 addition & 0 deletions components/browser/engine-gecko-beta/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
// As the Kotlin/Java API is the same for all ABIs it is not important which one we import here.
compileOnly Gecko.geckoview_beta_arm
testImplementation Gecko.geckoview_beta_arm

testImplementation Dependencies.androidx_test_core
testImplementation Dependencies.testing_junit
testImplementation Dependencies.testing_robolectric
Expand Down
16 changes: 11 additions & 5 deletions components/browser/engine-gecko/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,30 @@ android {

dependencies {
implementation project(':concept-engine')
implementation project(':concept-fetch')
implementation project(':support-ktx')
implementation project(':support-utils')
implementation Dependencies.kotlin_stdlib
implementation Dependencies.kotlin_coroutines

// We only compile against the ARM artifact. External module will decide which module to provide by build configuration.
// As the Kotlin/Java API is the same for all ABIs it is not important which one we import here.
compileOnly Gecko.geckoview_release_arm
testImplementation Gecko.geckoview_release_arm

implementation Dependencies.kotlin_stdlib
implementation Dependencies.kotlin_coroutines

testImplementation Dependencies.androidx_test_core

testImplementation Dependencies.testing_junit
testImplementation Dependencies.testing_robolectric
testImplementation Dependencies.testing_mockito

testImplementation Dependencies.testing_mockwebserver
testImplementation project(':support-test')
testImplementation project(':tooling-fetch-tests')

androidTestImplementation Dependencies.androidx_test_core
androidTestImplementation Dependencies.androidx_test_runner
androidTestImplementation Dependencies.androidx_test_rules
androidTestImplementation Gecko.geckoview_beta_arm
androidTestImplementation project(':tooling-fetch-tests')
}

apply from: '../../../publish.gradle'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* 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 mozilla.components.lib.fetch.geckoview

import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.MediumTest
import mozilla.components.browser.engine.gecko.fetch.GeckoViewFetchClient
import mozilla.components.concept.fetch.Client
import org.junit.Assert.assertTrue
import org.junit.Test

@MediumTest
@Suppress("TooManyFunctions")
class GeckoViewFetchTestCases : mozilla.components.tooling.fetch.tests.FetchTestCases() {
override fun createNewClient(): Client = GeckoViewFetchClient(ApplicationProvider.getApplicationContext())

@Test
@UiThreadTest
fun clientInstance() {
assertTrue(createNewClient() is GeckoViewFetchClient)
}

@Test
@UiThreadTest
override fun get200WithDefaultHeaders() {
super.get200WithDefaultHeaders()
}

@Test
@UiThreadTest
override fun get200WithGzippedBody() {
super.get200WithGzippedBody()
}

@Test
@UiThreadTest
override fun get200OverridingDefaultHeaders() {
super.get200OverridingDefaultHeaders()
}

@Test
@UiThreadTest
override fun get200WithUserAgent() {
super.get200WithUserAgent()
}

@Test
@UiThreadTest
override fun get200WithDuplicatedCacheControlRequestHeaders() {
super.get200WithDuplicatedCacheControlRequestHeaders()
}

@Test
@UiThreadTest
override fun get200WithDuplicatedCacheControlResponseHeaders() {
super.get200WithDuplicatedCacheControlResponseHeaders()
}

@Test
@UiThreadTest
override fun get200WithHeaders() {
super.get200WithHeaders()
}

@Test
@UiThreadTest
override fun get200WithReadTimeout() {
super.get200WithReadTimeout()
}

@Test
@UiThreadTest
override fun get200WithStringBody() {
super.get200WithStringBody()
}

@Test
@UiThreadTest
override fun get302FollowRedirects() {
super.get302FollowRedirects()
}

@Test
@UiThreadTest
override fun get302FollowRedirectsDisabled() {
super.get302FollowRedirectsDisabled()
}

@Test
@UiThreadTest
override fun get404WithBody() {
super.get404WithBody()
}

@Test
@UiThreadTest
override fun post200WithBody() {
super.post200WithBody()
}

@Test
@UiThreadTest
override fun put201FileUpload() {
super.put201FileUpload()
}

@Test
@UiThreadTest
override fun get200WithCookiePolicy() {
super.get200WithCookiePolicy()
}

@Test
@UiThreadTest
override fun get200WithContentTypeCharset() {
super.get200WithContentTypeCharset()
}

@Test
@UiThreadTest
override fun get200WithCacheControl() {
super.get200WithCacheControl()
}

@Test
@UiThreadTest
override fun getThrowsIOExceptionWhenHostNotReachable() {
super.getThrowsIOExceptionWhenHostNotReachable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ package mozilla.components.browser.engine.gecko

import android.content.Context
import android.util.AttributeSet
import mozilla.components.browser.engine.gecko.webextension.GeckoWebExtension
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy
import mozilla.components.concept.engine.EngineSessionState
import mozilla.components.concept.engine.EngineView
import mozilla.components.concept.engine.Settings
import mozilla.components.concept.engine.history.HistoryTrackingDelegate
import mozilla.components.concept.engine.webextension.WebExtension
import org.json.JSONObject
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoWebExecutor

/**
Expand All @@ -28,6 +32,18 @@ class GeckoEngine(
) : Engine {
private val executor by lazy { executorProvider.invoke() }

init {
runtime.delegate = GeckoRuntime.Delegate {
// On shutdown: The runtime is shutting down (possibly because of an unrecoverable error state). We crash
// the app here for two reasons:
// - We want to know about those unsolicited shutdowns and fix those issues.
// - We can't recover easily from this situation. Just continuing will leave us with an engine that
// doesn't do anything anymore.
@Suppress("TooGenericExceptionThrown")
throw RuntimeException("GeckoRuntime is shutting down")
}
}

/**
* Creates a new Gecko-based EngineView.
*/
Expand Down Expand Up @@ -59,6 +75,27 @@ class GeckoEngine(
executor.speculativeConnect(url)
}

/**
* See [Engine.installWebExtension].
*/
override fun installWebExtension(
id: String,
url: String,
allowContentMessaging: Boolean,
onSuccess: ((WebExtension) -> Unit),
onError: ((String, Throwable) -> Unit)
) {
GeckoWebExtension(id, url).also { ext ->
runtime.registerWebExtension(ext.nativeExtension).then({
onSuccess(ext)
GeckoResult<Void>()
}, {
throwable -> onError(id, throwable)
GeckoResult<Void>()
})
}
}

override fun name(): String = "Gecko"

/**
Expand All @@ -73,11 +110,15 @@ class GeckoEngine(
get() = runtime.settings.webFontsEnabled
set(value) { runtime.settings.webFontsEnabled = value }

override var automaticFontSizeAdjustment: Boolean
get() = runtime.settings.automaticFontSizeAdjustment
set(value) { runtime.settings.automaticFontSizeAdjustment = value }

override var trackingProtectionPolicy: TrackingProtectionPolicy?
get() = TrackingProtectionPolicy.select(runtime.settings.trackingProtectionCategories)
get() = TrackingProtectionPolicy.select(runtime.settings.contentBlocking.categories)
set(value) {
value?.let {
runtime.settings.trackingProtectionCategories = it.categories
runtime.settings.contentBlocking.categories = it.categories
defaultSettings?.trackingProtectionPolicy = value
}
}
Expand All @@ -95,15 +136,13 @@ class GeckoEngine(
set(value) { defaultSettings?.testingModeEnabled = value }

override var userAgentString: String?
// TODO if no default user agent string is provided we should
// return the engine default here, but we can't get to it in
// a practical way right now: https://bugzilla.mozilla.org/show_bug.cgi?id=1512997
get() = defaultSettings?.userAgentString
get() = defaultSettings?.userAgentString ?: GeckoSession.getDefaultUserAgent()
set(value) { defaultSettings?.userAgentString = value }
}.apply {
defaultSettings?.let {
this.javascriptEnabled = it.javascriptEnabled
this.webFontsEnabled = it.webFontsEnabled
this.automaticFontSizeAdjustment = it.automaticFontSizeAdjustment
this.trackingProtectionPolicy = it.trackingProtectionPolicy
this.remoteDebuggingEnabled = it.remoteDebuggingEnabled
this.testingModeEnabled = it.testingModeEnabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import mozilla.components.support.ktx.kotlin.isPhone
import mozilla.components.support.utils.DownloadUtils
import mozilla.components.support.utils.ThreadUtils
import org.mozilla.geckoview.AllowOrDeny
import org.mozilla.geckoview.ContentBlocking
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoSession
Expand All @@ -54,6 +55,7 @@ class GeckoEngineSession(
},
private val context: CoroutineContext = Dispatchers.IO
) : CoroutineScope, EngineSession() {

internal lateinit var geckoSession: GeckoSession
internal var currentUrl: String? = null
internal var job: Job = Job()
Expand Down Expand Up @@ -363,7 +365,7 @@ class GeckoEngineSession(
securityInfo: GeckoSession.ProgressDelegate.SecurityInformation
) {
// Ignore initial load of about:blank (see https://github.com/mozilla-mobile/android-components/issues/403)
if (initialLoad && securityInfo?.origin?.startsWith(MOZ_NULL_PRINCIPAL) == true) {
if (initialLoad && securityInfo.origin?.startsWith(MOZ_NULL_PRINCIPAL) == true) {
return
}

Expand Down Expand Up @@ -513,9 +515,10 @@ class GeckoEngineSession(
override fun onFocusRequest(session: GeckoSession) = Unit
}

private fun createTrackingProtectionDelegate() = GeckoSession.TrackingProtectionDelegate {
session, uri, _ ->
session?.let { uri?.let { notifyObservers { onTrackerBlocked(it) } } }
private fun createContentBlockingDelegate() = object : ContentBlocking.Delegate {
override fun onContentBlocked(session: GeckoSession, event: ContentBlocking.BlockEvent) {
notifyObservers { onTrackerBlocked(event.uri) }
}
}

private fun createPermissionDelegate() = object : GeckoSession.PermissionDelegate {
Expand All @@ -537,7 +540,7 @@ class GeckoEngineSession(
callback: GeckoSession.PermissionDelegate.MediaCallback
) {
val request = GeckoPermissionRequest.Media(
uri ?: "",
uri,
video?.toList() ?: emptyList(),
audio?.toList() ?: emptyList(),
callback)
Expand Down Expand Up @@ -610,7 +613,7 @@ class GeckoEngineSession(
geckoSession.navigationDelegate = createNavigationDelegate()
geckoSession.progressDelegate = createProgressDelegate()
geckoSession.contentDelegate = createContentDelegate()
geckoSession.trackingProtectionDelegate = createTrackingProtectionDelegate()
geckoSession.contentBlockingDelegate = createContentBlockingDelegate()
geckoSession.permissionDelegate = createPermissionDelegate()
geckoSession.promptDelegate = GeckoPromptDelegate(this)
geckoSession.historyDelegate = createHistoryDelegate()
Expand All @@ -619,7 +622,6 @@ class GeckoEngineSession(
companion object {
internal const val PROGRESS_START = 25
internal const val PROGRESS_STOP = 100
internal const val GECKO_STATE_KEY = "GECKO_STATE"
internal const val MOZ_NULL_PRINCIPAL = "moz-nullprincipal:"
internal const val ABOUT_BLANK = "about:blank"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.widget.FrameLayout
import androidx.core.view.ViewCompat
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineView
import org.mozilla.geckoview.GeckoResult

/**
* Gecko-based EngineView implementation.
Expand Down Expand Up @@ -60,7 +61,16 @@ class GeckoEngineView @JvmOverloads constructor(

override fun canScrollVerticallyDown() = true // waiting for this issue https://bugzilla.mozilla.org/show_bug.cgi?id=1507569

override fun captureThumbnail(onFinish: (Bitmap?) -> Unit) = Unit
override fun captureThumbnail(onFinish: (Bitmap?) -> Unit) {
val geckoResult = currentGeckoView.capturePixels()
geckoResult.then({ bitmap ->
onFinish(bitmap)
GeckoResult<Void>()
}, {
onFinish(null)
GeckoResult<Void>()
})
}

override fun setVerticalClipping(clippingHeight: Int) {
// no-op: requires GeckoView 68.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,12 @@ open class NestedGeckoView(context: Context) : GeckoView(context), NestedScrolli
override fun onTouchEvent(ev: MotionEvent): Boolean {
val event = MotionEvent.obtain(ev)
val action = ev.actionMasked
val eventY = event.y.toInt()

if (action == MotionEvent.ACTION_DOWN) {
nestedOffsetY = 0
}

val eventY = event.y.toInt()
event.offsetLocation(0f, nestedOffsetY.toFloat())

when (action) {
MotionEvent.ACTION_MOVE -> {
val allowScroll = !shouldPinOnScreen()
Expand Down
Loading

0 comments on commit ce15999

Please sign in to comment.