Loading components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −25 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -353,50 +354,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, request.hasUserGesture, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() var completedBy: String? = null val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, newCaller -> /* Debugging code for Android-components/issues/5127, will remove */ if (completedBy != null) { throw IllegalStateException("GeckoResult already completed by $completedBy, " + "new caller is $newCaller") } val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) /* Debugging code for Android-components/issues/5127, will remove */ completedBy = newCaller } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = request.hasUserGesture, shouldLoadUri = allowOrDeny triggeredByWebContent = request.hasUserGesture ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading components/browser/engine-gecko-beta/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt +177 −37 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ package mozilla.components.browser.engine.gecko import android.content.Intent import android.os.Handler import android.os.Message import androidx.test.ext.junit.runners.AndroidJUnit4 Loading Loading @@ -1155,7 +1156,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return RequestInterceptor.InterceptionResponse.Content("<h1>Hello World</h1>") } Loading @@ -1179,7 +1185,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return RequestInterceptor.InterceptionResponse.Url("https://mozilla.org") } Loading Loading @@ -1217,7 +1228,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return null } Loading Loading @@ -1845,39 +1861,173 @@ class GeckoEngineSessionTest { } @Test fun `onLoadRequest will notify observers if request was not intercepted`() { fun `onLoadRequest will notify onLaunchIntent observers if request was intercepted with app intent`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedUrl: String? = null var observedIntent: Intent? = null engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { "sample:about" -> RequestInterceptor.InterceptionResponse.AppIntent(mock(), "result") else -> null } } } engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedUrl = url observedIntent = appIntent } }) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNotNull(observedIntent) assertEquals("result", observedUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNotNull(observedIntent) assertEquals("result", observedUrl) } @Test fun `onLoadRequest will notify any observers if request was intercepted as url`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedLaunchIntentUrl: String? = null var observedLaunchIntent: Intent? = null var observedOnLoadRequestUrl: String? = null var observedTriggeredByRedirect: Boolean? = null var observedTriggeredByWebContent: Boolean? = null engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { "sample:about" -> RequestInterceptor.InterceptionResponse.Url("result") else -> null } } } engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedLaunchIntentUrl = url observedLaunchIntent = appIntent } override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean, shouldLoadUri: (Boolean, String) -> Unit triggeredByWebContent: Boolean ) { observedOnLoadRequestUrl = url observedTriggeredByRedirect = triggeredByRedirect observedUrl = url observedTriggeredByWebContent = triggeredByWebContent } }) navigationDelegate.value.onLoadRequest(mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNull(observedTriggeredByRedirect) assertNull(observedTriggeredByWebContent) assertNull(observedOnLoadRequestUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNull(observedTriggeredByRedirect) assertNull(observedTriggeredByWebContent) assertNull(observedOnLoadRequestUrl) } @Test fun `onLoadRequest will notify onLoadRequest observers if request was not intercepted`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedLaunchIntentUrl: String? = null var observedLaunchIntent: Intent? = null var observedOnLoadRequestUrl: String? = null var observedTriggeredByRedirect: Boolean? = null var observedTriggeredByWebContent: Boolean? = null engineSession.settings.requestInterceptor = null engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedLaunchIntentUrl = url observedLaunchIntent = appIntent } override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean ) { observedOnLoadRequestUrl = url observedTriggeredByRedirect = triggeredByRedirect observedTriggeredByWebContent = triggeredByWebContent } }) navigationDelegate.value.onLoadRequest(mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNotNull(observedTriggeredByRedirect) assertTrue(observedTriggeredByRedirect!!) assertEquals("sample:about", observedUrl) assertNotNull(observedTriggeredByWebContent) assertFalse(observedTriggeredByWebContent!!) assertEquals("sample:about", observedOnLoadRequestUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNotNull(observedTriggeredByRedirect) assertFalse(observedTriggeredByRedirect!!) assertEquals("sample:about", observedUrl) assertNotNull(observedTriggeredByWebContent) assertFalse(observedTriggeredByWebContent!!) assertEquals("sample:about", observedOnLoadRequestUrl) } @Test Loading @@ -1891,12 +2041,25 @@ class GeckoEngineSessionTest { var observedUrl: String? var observedTriggeredByWebContent: Boolean? engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { fakeUrl -> null else -> RequestInterceptor.InterceptionResponse.AppIntent(mock(), fakeUrl) } } } engineSession.register(object : EngineSession.Observer { override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean, shouldLoadUri: (Boolean, String) -> Unit triggeredByWebContent: Boolean ) { observedTriggeredByWebContent = triggeredByWebContent observedUrl = url Loading Loading @@ -1965,7 +2128,7 @@ class GeckoEngineSessionTest { } @Test fun `onLoadRequest will complete GeckoResult if no observer is available`() { fun `onLoadRequest will return correct GeckoResult if no observer is available`() { GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() Loading @@ -1975,29 +2138,6 @@ class GeckoEngineSessionTest { assertEquals(geckoResult!!, GeckoResult.fromValue(AllowOrDeny.ALLOW)) } @Test fun `onLoadRequest will not notify observers if request was intercepted`() { val defaultSettings = DefaultSettings(requestInterceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { return RequestInterceptor.InterceptionResponse.Content("<h1>Hello World</h1>") } }) val engineSession = GeckoEngineSession( mock(), geckoSessionProvider = geckoSessionProvider, defaultSettings = defaultSettings) captureDelegates() val observer: EngineSession.Observer = mock() engineSession.register(observer) val fakeUri = "sample:about" navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest(fakeUri, triggeredByRedirect = true)) verify(observer, never()).onLoadRequest(eq(fakeUri), anyBoolean(), anyBoolean(), any()) } @Test fun loadFlagsAreAligned() { assertEquals(LoadUrlFlags.BYPASS_CACHE, GeckoSession.LOAD_FLAGS_BYPASS_CACHE) Loading Loading @@ -2076,7 +2216,7 @@ class GeckoEngineSessionTest { } @Test fun managesStateOfFirstContenfulPaint() { fun managesStateOfFirstContentfulPaint() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) Loading components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −25 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -353,50 +354,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, request.hasUserGesture, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() var completedBy: String? = null val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, newCaller -> /* Debugging code for Android-components/issues/5127, will remove */ if (completedBy != null) { throw IllegalStateException("GeckoResult already completed by $completedBy, " + "new caller is $newCaller") } val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) /* Debugging code for Android-components/issues/5127, will remove */ completedBy = newCaller } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = request.hasUserGesture, shouldLoadUri = allowOrDeny triggeredByWebContent = request.hasUserGesture ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading components/browser/engine-gecko-nightly/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt +177 −37 File changed.Preview size limit exceeded, changes collapsed. Show changes components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −15 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -354,40 +355,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, requestFromWebContent, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, _ -> val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = requestFromWebContent, shouldLoadUri = allowOrDeny triggeredByWebContent = requestFromWebContent ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading Loading
components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −25 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -353,50 +354,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, request.hasUserGesture, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() var completedBy: String? = null val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, newCaller -> /* Debugging code for Android-components/issues/5127, will remove */ if (completedBy != null) { throw IllegalStateException("GeckoResult already completed by $completedBy, " + "new caller is $newCaller") } val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) /* Debugging code for Android-components/issues/5127, will remove */ completedBy = newCaller } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = request.hasUserGesture, shouldLoadUri = allowOrDeny triggeredByWebContent = request.hasUserGesture ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading
components/browser/engine-gecko-beta/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt +177 −37 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ package mozilla.components.browser.engine.gecko import android.content.Intent import android.os.Handler import android.os.Message import androidx.test.ext.junit.runners.AndroidJUnit4 Loading Loading @@ -1155,7 +1156,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return RequestInterceptor.InterceptionResponse.Content("<h1>Hello World</h1>") } Loading @@ -1179,7 +1185,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return RequestInterceptor.InterceptionResponse.Url("https://mozilla.org") } Loading Loading @@ -1217,7 +1228,12 @@ class GeckoEngineSessionTest { var interceptorCalledWithUri: String? = null val interceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { interceptorCalledWithUri = uri return null } Loading Loading @@ -1845,39 +1861,173 @@ class GeckoEngineSessionTest { } @Test fun `onLoadRequest will notify observers if request was not intercepted`() { fun `onLoadRequest will notify onLaunchIntent observers if request was intercepted with app intent`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedUrl: String? = null var observedIntent: Intent? = null engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { "sample:about" -> RequestInterceptor.InterceptionResponse.AppIntent(mock(), "result") else -> null } } } engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedUrl = url observedIntent = appIntent } }) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNotNull(observedIntent) assertEquals("result", observedUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNotNull(observedIntent) assertEquals("result", observedUrl) } @Test fun `onLoadRequest will notify any observers if request was intercepted as url`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedLaunchIntentUrl: String? = null var observedLaunchIntent: Intent? = null var observedOnLoadRequestUrl: String? = null var observedTriggeredByRedirect: Boolean? = null var observedTriggeredByWebContent: Boolean? = null engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { "sample:about" -> RequestInterceptor.InterceptionResponse.Url("result") else -> null } } } engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedLaunchIntentUrl = url observedLaunchIntent = appIntent } override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean, shouldLoadUri: (Boolean, String) -> Unit triggeredByWebContent: Boolean ) { observedOnLoadRequestUrl = url observedTriggeredByRedirect = triggeredByRedirect observedUrl = url observedTriggeredByWebContent = triggeredByWebContent } }) navigationDelegate.value.onLoadRequest(mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNull(observedTriggeredByRedirect) assertNull(observedTriggeredByWebContent) assertNull(observedOnLoadRequestUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNull(observedTriggeredByRedirect) assertNull(observedTriggeredByWebContent) assertNull(observedOnLoadRequestUrl) } @Test fun `onLoadRequest will notify onLoadRequest observers if request was not intercepted`() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() var observedLaunchIntentUrl: String? = null var observedLaunchIntent: Intent? = null var observedOnLoadRequestUrl: String? = null var observedTriggeredByRedirect: Boolean? = null var observedTriggeredByWebContent: Boolean? = null engineSession.settings.requestInterceptor = null engineSession.register(object : EngineSession.Observer { override fun onLaunchIntentRequest( url: String, appIntent: Intent? ) { observedLaunchIntentUrl = url observedLaunchIntent = appIntent } override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean ) { observedOnLoadRequestUrl = url observedTriggeredByRedirect = triggeredByRedirect observedTriggeredByWebContent = triggeredByWebContent } }) navigationDelegate.value.onLoadRequest(mock(), mockLoadRequest("sample:about", triggeredByRedirect = true)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNotNull(observedTriggeredByRedirect) assertTrue(observedTriggeredByRedirect!!) assertEquals("sample:about", observedUrl) assertNotNull(observedTriggeredByWebContent) assertFalse(observedTriggeredByWebContent!!) assertEquals("sample:about", observedOnLoadRequestUrl) navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest("sample:about", triggeredByRedirect = false)) assertNull(observedLaunchIntentUrl) assertNull(observedLaunchIntent) assertNotNull(observedTriggeredByRedirect) assertFalse(observedTriggeredByRedirect!!) assertEquals("sample:about", observedUrl) assertNotNull(observedTriggeredByWebContent) assertFalse(observedTriggeredByWebContent!!) assertEquals("sample:about", observedOnLoadRequestUrl) } @Test Loading @@ -1891,12 +2041,25 @@ class GeckoEngineSessionTest { var observedUrl: String? var observedTriggeredByWebContent: Boolean? engineSession.settings.requestInterceptor = object : RequestInterceptor { override fun onLoadRequest( engineSession: EngineSession, uri: String, hasUserGesture: Boolean, isSameDomain: Boolean ): RequestInterceptor.InterceptionResponse? { return when (uri) { fakeUrl -> null else -> RequestInterceptor.InterceptionResponse.AppIntent(mock(), fakeUrl) } } } engineSession.register(object : EngineSession.Observer { override fun onLoadRequest( url: String, triggeredByRedirect: Boolean, triggeredByWebContent: Boolean, shouldLoadUri: (Boolean, String) -> Unit triggeredByWebContent: Boolean ) { observedTriggeredByWebContent = triggeredByWebContent observedUrl = url Loading Loading @@ -1965,7 +2128,7 @@ class GeckoEngineSessionTest { } @Test fun `onLoadRequest will complete GeckoResult if no observer is available`() { fun `onLoadRequest will return correct GeckoResult if no observer is available`() { GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) captureDelegates() Loading @@ -1975,29 +2138,6 @@ class GeckoEngineSessionTest { assertEquals(geckoResult!!, GeckoResult.fromValue(AllowOrDeny.ALLOW)) } @Test fun `onLoadRequest will not notify observers if request was intercepted`() { val defaultSettings = DefaultSettings(requestInterceptor = object : RequestInterceptor { override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? { return RequestInterceptor.InterceptionResponse.Content("<h1>Hello World</h1>") } }) val engineSession = GeckoEngineSession( mock(), geckoSessionProvider = geckoSessionProvider, defaultSettings = defaultSettings) captureDelegates() val observer: EngineSession.Observer = mock() engineSession.register(observer) val fakeUri = "sample:about" navigationDelegate.value.onLoadRequest( mock(), mockLoadRequest(fakeUri, triggeredByRedirect = true)) verify(observer, never()).onLoadRequest(eq(fakeUri), anyBoolean(), anyBoolean(), any()) } @Test fun loadFlagsAreAligned() { assertEquals(LoadUrlFlags.BYPASS_CACHE, GeckoSession.LOAD_FLAGS_BYPASS_CACHE) Loading Loading @@ -2076,7 +2216,7 @@ class GeckoEngineSessionTest { } @Test fun managesStateOfFirstContenfulPaint() { fun managesStateOfFirstContentfulPaint() { val engineSession = GeckoEngineSession(mock(), geckoSessionProvider = geckoSessionProvider) Loading
components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −25 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -353,50 +354,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, request.hasUserGesture, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() var completedBy: String? = null val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, newCaller -> /* Debugging code for Android-components/issues/5127, will remove */ if (completedBy != null) { throw IllegalStateException("GeckoResult already completed by $completedBy, " + "new caller is $newCaller") } val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) /* Debugging code for Android-components/issues/5127, will remove */ completedBy = newCaller } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = request.hasUserGesture, shouldLoadUri = allowOrDeny triggeredByWebContent = request.hasUserGesture ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading
components/browser/engine-gecko-nightly/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt +177 −37 File changed.Preview size limit exceeded, changes collapsed. Show changes
components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +13 −15 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import mozilla.components.support.ktx.android.util.Base64 import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.json.JSONObject import org.mozilla.geckoview.AllowOrDeny import org.mozilla.geckoview.ContentBlocking Loading Loading @@ -354,40 +355,37 @@ class GeckoEngineSession( return GeckoResult.fromValue(AllowOrDeny.ALLOW) } val isSameDomain = this@GeckoEngineSession.currentUrl?.tryGetHostFromUrl() == request.uri.tryGetHostFromUrl() val response = settings.requestInterceptor?.onLoadRequest( this@GeckoEngineSession, request.uri request.uri, requestFromWebContent, isSameDomain )?.apply { when (this) { is InterceptionResponse.Content -> loadData(data, mimeType, encoding) is InterceptionResponse.Url -> loadUrl(url) is InterceptionResponse.AppIntent -> { notifyObservers { onLaunchIntentRequest(url = url, appIntent = appIntent) } } } } return if (response != null) { GeckoResult.fromValue(AllowOrDeny.DENY) } else if (!isObserved()) { GeckoResult.fromValue(AllowOrDeny.ALLOW) } else { val geckoResult: GeckoResult<AllowOrDeny> = GeckoResult() val allowOrDeny: (Boolean, String) -> Unit = { shouldAllow, _ -> val result = if (shouldAllow) AllowOrDeny.ALLOW else AllowOrDeny.DENY geckoResult.complete(result) } notifyObservers { // Unlike the name LoadRequest.isRedirect may imply this flag is not about http redirects. The flag // is "True if and only if the request was triggered by an HTTP redirect." // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1545170 onLoadRequest( url = request.uri, triggeredByRedirect = request.isRedirect, triggeredByWebContent = requestFromWebContent, shouldLoadUri = allowOrDeny triggeredByWebContent = requestFromWebContent ) } geckoResult GeckoResult.fromValue(AllowOrDeny.ALLOW) } } Loading