Commit 3fd20c1a authored by MozLando's avatar MozLando
Browse files

Merge #6374 #6387

6374: For #5866: Don't crash when failed to launch new window request in custom tab r=jonalmeida a=rocketsroger



6387: Fixes #6386 - Import v9.0.0 sources r=jonalmeida a=miketaylr

https://github.com/mozilla-mobile/android-components/issues/6386
https://bugzilla.mozilla.org/show_bug.cgi?id=1624694

Co-authored-by: default avatarRoger Yang <royang@mozilla.com>
Co-authored-by: default avatarMike Taylor <miket@mozilla.com>
......@@ -39,6 +39,7 @@ dependencies {
implementation project(':support-ktx')
implementation project(':support-utils')
implementation project(':ui-icons')
implementation project(':lib-crash')
implementation Dependencies.androidx_core_ktx
implementation Dependencies.kotlin_stdlib
......
......@@ -5,7 +5,9 @@
package mozilla.components.feature.customtabs
import android.app.Activity
import android.content.ActivityNotFoundException
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.net.toUri
import kotlinx.coroutines.CoroutineScope
......@@ -17,6 +19,7 @@ import mozilla.components.browser.state.selector.findCustomTab
import mozilla.components.browser.state.state.CustomTabConfig
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.window.WindowRequest
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
......@@ -29,7 +32,8 @@ const val SHORTCUT_CATEGORY = "mozilla.components.pwa.category.SHORTCUT"
class CustomTabWindowFeature(
private val activity: Activity,
private val store: BrowserStore,
private val sessionId: String
private val sessionId: String,
private val crashReporter: CrashReporter? = null
) : LifecycleAwareFeature {
private var scope: CoroutineScope? = null
......@@ -39,7 +43,7 @@ class CustomTabWindowFeature(
* new custom tab with the same styling and layout
*/
@Suppress("ComplexMethod")
@VisibleForTesting
@VisibleForTesting(otherwise = PRIVATE)
internal fun configToIntent(config: CustomTabConfig?): CustomTabsIntent {
val intent = CustomTabsIntent.Builder().apply {
setInstantAppsEnabled(false)
......@@ -72,7 +76,11 @@ class CustomTabWindowFeature(
val windowRequest = state.content.windowRequest
if (windowRequest?.type == WindowRequest.Type.OPEN) {
val intent = configToIntent(state.config)
intent.launchUrl(activity, windowRequest.url.toUri())
try {
intent.launchUrl(activity, windowRequest.url.toUri())
} catch (e: ActivityNotFoundException) {
crashReporter?.submitCaughtException(e)
}
store.dispatch(ContentAction.ConsumeWindowRequestAction(sessionId))
}
}
......
......@@ -5,6 +5,7 @@
package mozilla.components.feature.customtabs
import android.app.Activity
import android.content.ActivityNotFoundException
import android.graphics.Color
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.test.TestCoroutineDispatcher
......@@ -16,6 +17,7 @@ import mozilla.components.browser.state.state.CustomTabMenuItem
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.window.WindowRequest
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.support.test.any
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.mock
......@@ -133,4 +135,19 @@ class CustomTabWindowFeatureTest {
private fun assertEqualConfigs(expected: CustomTabConfig, actual: CustomTabConfig) {
assertEquals(expected.copy(id = ""), actual.copy(id = ""))
}
@Test
fun `handles failed request to open window`() {
val crashReporter: CrashReporter = mock()
val feature = CustomTabWindowFeature(activity, store, sessionId, crashReporter)
feature.start()
val windowRequest: WindowRequest = mock()
val exception: ActivityNotFoundException = mock()
whenever(windowRequest.type).thenReturn(WindowRequest.Type.OPEN)
whenever(windowRequest.url).thenReturn("https://www.firefox.com")
whenever(activity.startActivity(any(), any())).thenThrow(exception)
store.dispatch(ContentAction.UpdateWindowRequestAction(sessionId, windowRequest)).joinBlocking()
verify(crashReporter).submitCaughtException(exception)
}
}
......@@ -27,11 +27,10 @@ AboutCompat.prototype = {
const channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
channel.owner = (Services.scriptSecurityManager.createContentPrincipal ||
Services.scriptSecurityManager.createCodebasePrincipal)(
uri,
aLoadInfo.originAttributes
);
channel.owner = (
Services.scriptSecurityManager.createContentPrincipal ||
Services.scriptSecurityManager.createCodebasePrincipal
)(uri, aLoadInfo.originAttributes);
return channel;
},
};
[{
[
{
"namespace": "aboutCompat",
"description": "Enables the about:compat page"
}]
}
]
......@@ -7,8 +7,8 @@
/* globals module, require */
// This is a hack for the tests.
if (typeof getMatchPatternsForGoogleURL === "undefined") {
var getMatchPatternsForGoogleURL = require("../lib/google");
if (typeof InterventionHelpers === "undefined") {
var InterventionHelpers = require("../lib/intervention_helpers");
}
/**
......@@ -112,28 +112,37 @@ const AVAILABLE_INJECTIONS = [
},
},
{
id: "bug1577245",
id: "bug1623375",
platform: "android",
domain: "Salesforce communities",
bug: "1577245",
bug: "1623375",
contentScripts: {
matches: [
"https://faq.usps.com/*",
"https://help.duo.com/*",
"https://my211.force.com/*",
"https://support.paypay.ne.jp/*",
"https://usps.force.com/*",
"https://help.twitch.tv/*",
"https://support.sonos.com/*",
"https://us.community.sony.com/*",
"https://help.shopee.ph/*",
"https://exclusions.ustr.gov/*",
"https://help.doordash.com/*",
],
matches: [].concat(
[
"https://faq.usps.com/*",
"https://help.duo.com/*",
"https://my211.force.com/*",
"https://support.paypay.ne.jp/*",
"https://usps.force.com/*",
"https://help.twitch.tv/*",
"https://support.sonos.com/*",
"https://us.community.sony.com/*",
"https://help.shopee.ph/*",
"https://exclusions.ustr.gov/*",
"https://help.doordash.com/*",
"https://community.snowflake.com/*",
"https://tivoidp.tivo.com/*",
],
InterventionHelpers.matchPatternsForTLDs(
"*://support.ancestry.",
"/*",
["ca", "co.uk", "com", "com.au", "de", "fr", "it", "mx", "se"]
)
),
js: [
{
file:
"injections/js/bug1577245-salesforce-communities-hide-unsupported.js",
"injections/js/bug1623375-salesforce-communities-hide-unsupported.js",
},
],
},
......@@ -152,20 +161,6 @@ const AVAILABLE_INJECTIONS = [
],
},
},
{
id: "bug1518781",
platform: "desktop",
domain: "twitch.tv",
bug: "1518781",
contentScripts: {
matches: ["*://*.twitch.tv/*"],
css: [
{
file: "injections/css/bug1518781-twitch.tv-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1551672",
platform: "android",
......@@ -184,7 +179,6 @@ const AVAILABLE_INJECTIONS = [
bug: "1577870",
data: {
urls: [
"https://*.linkedin.com/tscp-serving/dtag*",
"https://ads-us.rd.linksynergy.com/as.php*",
"https://www.office.com/logout?sid*",
],
......@@ -195,21 +189,6 @@ const AVAILABLE_INJECTIONS = [
},
customFunc: "noSniffFix",
},
{
id: "bug1432935-discord",
platform: "desktop",
domain: "discordapp.com",
bug: "1432935",
contentScripts: {
matches: ["*://discordapp.com/*"],
css: [
{
file:
"injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css",
},
],
},
},
{
id: "bug1561371",
platform: "android",
......@@ -341,20 +320,6 @@ const AVAILABLE_INJECTIONS = [
],
},
},
{
id: "bug1575017",
platform: "desktop",
domain: "dunkindonuts.com",
bug: "1575017",
contentScripts: {
matches: ["*://*.dunkindonuts.com/en/sign-in*"],
css: [
{
file: "injections/css/bug1575017-dunkindonuts.com-flex-basis.css",
},
],
},
},
{
id: "bug1577270",
platform: "android",
......@@ -389,7 +354,10 @@ const AVAILABLE_INJECTIONS = [
domain: "maps.google.com",
bug: "1605611",
contentScripts: {
matches: getMatchPatternsForGoogleURL("www.google", "maps*"),
matches: InterventionHelpers.matchPatternsForGoogle(
"*://www.google.",
"/maps*"
),
css: [
{
file: "injections/css/bug1605611-maps.google.com-directions-time.css",
......@@ -459,6 +427,17 @@ const AVAILABLE_INJECTIONS = [
],
},
},
{
id: "bug1622062",
platform: "android",
domain: "$.detectSwipe fix",
bug: "1622062",
data: {
urls: ["https://eu.stemwijzer.nl/public/js/votematch.vendors.js"],
types: ["script"],
},
customFunc: "detectSwipeFix",
},
];
module.exports = AVAILABLE_INJECTIONS;
......@@ -7,8 +7,8 @@
/* globals browser, module, require */
// This is a hack for the tests.
if (typeof getMatchPatternsForGoogleURL === "undefined") {
var getMatchPatternsForGoogleURL = require("../lib/google");
if (typeof InterventionHelpers === "undefined") {
var InterventionHelpers = require("../lib/intervention_helpers");
}
/**
......@@ -422,28 +422,6 @@ const AVAILABLE_UA_OVERRIDES = [
},
},
},
{
/*
* Bug 1577240 - UA override for heb.com on Firefox for Android
* WebCompat issue #33613 - https://webcompat.com/issues/33613
*
* heb.com shows desktop site on Firefox for Android for some pages based on
* UA detection. Spoofing as Chrome allows to get mobile site.
*/
id: "bug1577240",
platform: "android",
domain: "heb.com",
bug: "1577240",
config: {
matches: ["*://*.heb.com/*"],
uaTransformer: originalUA => {
return (
UAHelpers.getPrefix(originalUA) +
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
);
},
},
},
{
/*
* Bug 1577250 - UA override for homebook.pl on Firefox for Android
......@@ -565,27 +543,6 @@ const AVAILABLE_UA_OVERRIDES = [
},
},
},
{
/*
* Bug 1442050 - UA overrides for my.nintendo.com
* Webcompat issue #12887 - https://webcompat.com/issues/12887
*
* Nintendo ships a broken version of their mobile interface to mobile
* browsers that are not Chrome or Safari. In our tests, appending the
* "AppleWebKit" identifier to the UA string results in a version that
* works very well.
*/
id: "bug1442050",
platform: "android",
domain: "nintendo.com",
bug: "1442050",
config: {
matches: ["*://my.nintendo.com/*"],
uaTransformer: originalUA => {
return originalUA + " AppleWebKit";
},
},
},
{
/*
* Bug 1621065 - UA overrides for bracketchallenge.ncaa.com
......@@ -607,6 +564,71 @@ const AVAILABLE_UA_OVERRIDES = [
},
},
},
{
/*
* Bug 1622063 - UA override for wp1-ext.usps.gov
* Webcompat issue #29867 - https://webcompat.com/issues/29867
*
* The Job Search site for USPS does not work for Firefox Mobile
* browsers (a 500 is returned).
*/
id: "bug1622063",
platform: "android",
domain: "wp1-ext.usps.gov",
bug: "1622063",
config: {
matches: ["*://wp1-ext.usps.gov/*"],
uaTransformer: originalUA => {
return UAHelpers.getDeviceAppropriateChromeUA();
},
},
},
{
/*
* Bug 1622059 - UA overrides for img.weblogssl.com breakage
* Webcompat issue #49166 - https://webcompat.com/issues/49166
* Webcompat issue #48650 - https://webcompat.com/issues/48650
* Webcompat issue #48787 - https://webcompat.com/issues/48787
*
* These pages throw due to some poor UA sniffing assumptions, so
* we add a "Version/99.0" token so comments will be visible. They
* all share a common file hosted at:
* https://img.weblogssl.com/LPbackend/prod/v2/js
*/
id: "bug1622059",
platform: "android",
domain: "img.weblogssl.com",
bug: "1622059",
config: {
matches: [
"*://www.genbeta.com/*",
"*://www.xataka.com/*",
"*://www.xatakandroid.com/*",
],
uaTransformer: originalUA => {
return originalUA + " Version/99.0";
},
},
},
{
/*
* Bug 1622081 - UA override for m2.bmo.com
* Webcompat issue #45019 - https://webcompat.com/issues/45019
*
* Unless the UA string contains "Chrome", m2.bmo.com will
* display a modal saying the browser is out-of-date.
*/
id: "bug1622081",
platform: "android",
domain: "m2.bmo.com",
bug: "1622081",
config: {
matches: ["*://m2.bmo.com/*"],
uaTransformer: originalUA => {
return originalUA + " Chrome";
},
},
},
];
const UAHelpers = {
......
......@@ -6,16 +6,20 @@
{
"name": "onPrefChange",
"type": "function",
"parameters": [{
"name": "name",
"type": "string",
"description": "The preference which changed"
}],
"extraParameters": [{
"name": "name",
"type": "string",
"description": "The preference to monitor"
}]
"parameters": [
{
"name": "name",
"type": "string",
"description": "The preference which changed"
}
],
"extraParameters": [
{
"name": "name",
"type": "string",
"description": "The preference to monitor"
}
]
}
],
"functions": [
......@@ -23,11 +27,13 @@
"name": "getPref",
"type": "function",
"description": "Get a preference's value",
"parameters": [{
"name": "name",
"type": "string",
"description": "The preference name"
}],
"parameters": [
{
"name": "name",
"type": "string",
"description": "The preference name"
}
],
"async": true
},
{
......
/**
* discordapp.com - -webkit-scrollbar dependency causes visible white line
* Part of Bug #1432935 - https://bugzilla.mozilla.org/show_bug.cgi?id=1432935
* WebCompat issue #7919 - https://webcompat.com/issues/7919
*
* Discord depends on -webkit-scrollbar for styling and hiding their scrollbars
* in the UI. Previously, the scrollbars overlapped content permanently.
* However, this issue seems to be addressed now, but a small white line
* still remains. While Discord is working on this, let's get rid of these
* lines.
*/
.themeGhostHairline-DBD-2d .pad-29zQak,
.themeGhostHairlineChannels-3G0x9_ .pad-29zQak {
width: 3px !important;
left: -3px !important;
}
/**
* twitch.tv - Comment interaction button is overlayed by scrollbar
* Bug #1518781 - https://bugzilla.mozilla.org/show_bug.cgi?id=1518781
*
* The interaction buttons in Twitch' chat are partly overlayed by the
* scrollbar, which makes them hard to use. Twitch uses
* ::-webkit-scrollbar to make the scrollbar thinner, which isn't working in
* Firefox.
* Given that even scrollbar-width: thin; is not enough (see Bugzilla), let's
* remove it entirely.
*/
.video-chat__message-list-wrapper {
scrollbar-width: none;
}
/**
* dunkindonuts.com - form input fields are small and misaligned
* Bug #1575017 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575017
* WebCompat issue #28742 - https://webcompat.com/issues/28742
*
* Form input fields are small and misaligned due to flex-basis: min-content;
* applied on their parent element. Setting it to auto fixes the issue
*/
.grid__item {
flex-basis: auto;
}
"use strict";
/**
* Salesforce Communities - Hide unsupported message in Firefox for Android
* Bug 1623375 - Salesforce Communities - Hide unsupported message in Firefox for Android
*
* Sites based on Salesforce Communities are showing unsupported message.
* See the full list here:
......
......@@ -36,6 +36,25 @@ const replaceStringInRequest = (
};
const CUSTOM_FUNCTIONS = {
detectSwipeFix: injection => {
const { urls, types } = injection.data;
const listener = (injection.data.listener = ({ requestId }) => {
replaceStringInRequest(
requestId,
"preventDefault:true",
"preventDefault:false"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
"blocking",
]);
},
detectSwipeFixDisable: injection => {
const { listener } = injection.data;
browser.webRequest.onBeforeRequest.removeListener(listener);
delete injection.data.listener;
},
noSniffFix: injection => {
const { urls, contentType } = injection.data;
const listener = (injection.data.listener = e => {
......
......@@ -208,8 +208,26 @@ const GOOGLE_TLDS = [
"co.zw",
];
function getMatchPatternsForGoogleURL(url, path = "*") {
return GOOGLE_TLDS.map(domain => `*://${url}.${domain}/${path}`);
}
var InterventionHelpers = {
/**
* Useful helper to generate a list of domains with a fixed base domain and
* multiple country-TLDs or other cases with various TLDs.