summaryrefslogtreecommitdiffstats
path: root/mobile
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
commitfbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch)
tree4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /mobile
parentReleasing progress-linux version 124.0.1-1~progress7.99u1. (diff)
downloadfirefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz
firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mobile')
-rw-r--r--mobile/android/actors/GeckoViewContentParent.sys.mjs2
-rw-r--r--mobile/android/actors/SelectionActionDelegateChild.sys.mjs8
-rw-r--r--mobile/android/annotations/build.gradle6
-rw-r--r--mobile/android/app/geckoview-prefs.js12
-rw-r--r--mobile/android/chrome/geckoview/SessionStateAggregator.js17
-rw-r--r--mobile/android/chrome/geckoview/config.js4
-rw-r--r--mobile/android/chrome/geckoview/geckoview.js6
-rw-r--r--mobile/android/components/extensions/ext-android.js2
-rw-r--r--mobile/android/components/extensions/ext-browserAction.js4
-rw-r--r--mobile/android/components/extensions/ext-downloads.js20
-rw-r--r--mobile/android/components/extensions/ext-pageAction.js4
-rw-r--r--mobile/android/components/extensions/ext-tabs.js15
-rw-r--r--mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html4
-rw-r--r--mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html12
-rw-r--r--mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html2
-rw-r--r--mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html6
-rw-r--r--mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js2
-rw-r--r--mobile/android/components/geckoview/FilePickerDelegate.sys.mjs4
-rw-r--r--mobile/android/components/geckoview/GeckoViewPrompter.sys.mjs2
-rw-r--r--mobile/android/components/geckoview/GeckoViewPush.sys.mjs9
-rw-r--r--mobile/android/components/geckoview/GeckoViewStartup.sys.mjs4
-rw-r--r--mobile/android/components/geckoview/LoginStorageDelegate.sys.mjs9
-rw-r--r--mobile/android/docs/geckoview/design/priority-hint.rst2
-rw-r--r--mobile/android/docs/geckoview/design/save-to-pdf.rst14
-rw-r--r--mobile/android/exoplayer2/build.gradle10
-rw-r--r--mobile/android/geckoview/api.txt11
-rw-r--r--mobile/android/geckoview/build.gradle8
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-browser-action.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-page-action.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/borderify.js1
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/border-48.pngbin0 -> 225 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/icon.svg1
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/manifest.json26
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify/manifest.json3
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/clickToRequestPermission.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/manifest.json14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/request-permission.js10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/redirect-to-android-resource/background.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/web_extensions/update-postpone-1/background.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/clickToReplace.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/push/sw.js2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/scroll.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch-action.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touchstart.html2
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt2
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt1
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoAppShellTest.kt1
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt1
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeolocationTest.kt3
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/HistoryDelegateTest.kt5
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocaleTest.kt12
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt163
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/OpenWindowTest.kt8
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PdfCreationTest.kt12
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt54
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt22
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/RuntimeSettingsTest.kt3
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ScreenshotTest.kt5
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt18
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestContentProvider.java19
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt42
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TrackingPermissionService.java3
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/VideoCaptureTest.kt58
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt168
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebNotificationTest.kt15
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt3
-rw-r--r--mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java3
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java2
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java15
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoDragAndDrop.java6
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java9
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/MediaDrmProxy.java1
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/LocaleUtils.java32
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java17
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java47
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java26
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java30
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java4
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java6
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java54
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md25
-rw-r--r--mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/LocaleUtilsTest.java47
-rw-r--r--mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java5
-rw-r--r--mobile/android/gradle/with_gecko_binaries.gradle4
-rw-r--r--mobile/android/installer/package-manifest.in2
-rw-r--r--mobile/android/modules/geckoview/ChildCrashHandler.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewContent.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewMediaControl.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewModule.sys.mjs4
-rw-r--r--mobile/android/modules/geckoview/GeckoViewNavigation.sys.mjs13
-rw-r--r--mobile/android/modules/geckoview/GeckoViewProcessHangMonitor.sys.mjs4
-rw-r--r--mobile/android/modules/geckoview/GeckoViewProgress.sys.mjs5
-rw-r--r--mobile/android/modules/geckoview/GeckoViewPushController.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewSelectionAction.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewSessionStore.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewStorageController.sys.mjs6
-rw-r--r--mobile/android/modules/geckoview/GeckoViewTab.sys.mjs4
-rw-r--r--mobile/android/modules/geckoview/GeckoViewTelemetry.sys.mjs12
-rw-r--r--mobile/android/modules/geckoview/GeckoViewTestUtils.sys.mjs2
-rw-r--r--mobile/android/modules/geckoview/GeckoViewTranslations.sys.mjs8
-rw-r--r--mobile/android/modules/geckoview/GeckoViewUtils.sys.mjs10
-rw-r--r--mobile/android/modules/geckoview/GeckoViewWebExtension.sys.mjs31
-rw-r--r--mobile/android/modules/geckoview/LoadURIDelegate.sys.mjs6
-rw-r--r--mobile/android/modules/geckoview/Messaging.sys.mjs4
-rw-r--r--mobile/android/modules/geckoview/test/xpcshell/test_ChildCrashHandler.js4
-rw-r--r--mobile/android/test_runner/src/main/java/org/mozilla/geckoview/test_runner/TestRunnerActivity.java5
-rw-r--r--mobile/ios/app.mozbuild10
-rw-r--r--mobile/ios/build.mk5
-rw-r--r--mobile/ios/config/mozconfigs/ios-sim/debug3
-rw-r--r--mobile/ios/config/mozconfigs/ios-sim/opt6
-rw-r--r--mobile/ios/config/mozconfigs/ios/debug3
-rw-r--r--mobile/ios/config/mozconfigs/ios/debug-searchfox8
-rw-r--r--mobile/ios/config/mozconfigs/ios/opt5
-rw-r--r--mobile/ios/installer/Makefile.in11
-rw-r--r--mobile/ios/installer/allowed-dupes.mn26
-rw-r--r--mobile/ios/moz.build10
-rw-r--r--mobile/ios/moz.configure16
123 files changed, 1159 insertions, 330 deletions
diff --git a/mobile/android/actors/GeckoViewContentParent.sys.mjs b/mobile/android/actors/GeckoViewContentParent.sys.mjs
index 354489054a..e666040b5e 100644
--- a/mobile/android/actors/GeckoViewContentParent.sys.mjs
+++ b/mobile/android/actors/GeckoViewContentParent.sys.mjs
@@ -62,7 +62,7 @@ export class GeckoViewContentParent extends GeckoViewActorParent {
const progressListener = {
QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener"]),
- onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
+ onLocationChange(aWebProgress) {
if (!aWebProgress.isTopLevel) {
return;
}
diff --git a/mobile/android/actors/SelectionActionDelegateChild.sys.mjs b/mobile/android/actors/SelectionActionDelegateChild.sys.mjs
index 9f05906e09..f9c09de11f 100644
--- a/mobile/android/actors/SelectionActionDelegateChild.sys.mjs
+++ b/mobile/android/actors/SelectionActionDelegateChild.sys.mjs
@@ -97,17 +97,17 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild {
{
id: "org.mozilla.geckoview.COLLAPSE_TO_START",
predicate: e => !e.collapsed && e.selectionEditable,
- perform: e => this.docShell.doCommand("cmd_moveLeft"),
+ perform: () => this.docShell.doCommand("cmd_moveLeft"),
},
{
id: "org.mozilla.geckoview.COLLAPSE_TO_END",
predicate: e => !e.collapsed && e.selectionEditable,
- perform: e => this.docShell.doCommand("cmd_moveRight"),
+ perform: () => this.docShell.doCommand("cmd_moveRight"),
},
{
id: "org.mozilla.geckoview.UNSELECT",
predicate: e => !e.collapsed && !e.selectionEditable,
- perform: e => this.docShell.doCommand("cmd_selectNone"),
+ perform: () => this.docShell.doCommand("cmd_selectNone"),
},
{
id: "org.mozilla.geckoview.SELECT_ALL",
@@ -134,7 +134,7 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild {
}
return true;
},
- perform: e => this.docShell.doCommand("cmd_selectAll"),
+ perform: () => this.docShell.doCommand("cmd_selectAll"),
},
];
diff --git a/mobile/android/annotations/build.gradle b/mobile/android/annotations/build.gradle
index 147531b251..aa531dd0a9 100644
--- a/mobile/android/annotations/build.gradle
+++ b/mobile/android/annotations/build.gradle
@@ -10,5 +10,7 @@ dependencies {
implementation 'com.android.tools.lint:lint-checks:30.4.2'
}
-sourceCompatibility = JavaVersion.VERSION_17
-targetCompatibility = JavaVersion.VERSION_17
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
diff --git a/mobile/android/app/geckoview-prefs.js b/mobile/android/app/geckoview-prefs.js
index d71f7f49e8..6d136b1a0a 100644
--- a/mobile/android/app/geckoview-prefs.js
+++ b/mobile/android/app/geckoview-prefs.js
@@ -142,12 +142,10 @@ pref("browser.sessionstore.max_tabs_undo", 10);
pref("browser.sessionstore.privacy_level", 0);
pref("browser.sessionstore.resume_from_crash", true);
-// Bug 1809922 to enable translations
-#ifdef NIGHTLY_BUILD
- pref("browser.translations.enable", true);
- // Used for mocking data for GeckoView Translations tests, should use in addition with an automation check.
- pref("browser.translations.geckoview.enableAllTestMocks", false);
-#endif
+// Enables the translations engine
+pref("browser.translations.enable", true);
+// Used for mocking data for GeckoView Translations tests, should use in addition with an automation check.
+pref("browser.translations.geckoview.enableAllTestMocks", false);
// SSL error page behaviour (bug 437372)
pref("browser.xul.error_pages.expert_bad_cert", false);
@@ -214,7 +212,7 @@ pref("dom.webshare.enabled", true);
pref("extensions.abuseReport.amWebAPI.enabled", false);
// Disable add-ons that are not installed by the user in all scopes by default (See the SCOPE
-// constants in AddonManager.jsm for values to use here, and Bug 1405528 for a rationale)
+// constants in AddonManager.sys.mjs for values to use here, and Bug 1405528 for a rationale)
pref("extensions.autoDisableScopes", 15);
pref("extensions.enabledScopes", 5);
diff --git a/mobile/android/chrome/geckoview/SessionStateAggregator.js b/mobile/android/chrome/geckoview/SessionStateAggregator.js
index ede17328ac..e41c31ba06 100644
--- a/mobile/android/chrome/geckoview/SessionStateAggregator.js
+++ b/mobile/android/chrome/geckoview/SessionStateAggregator.js
@@ -29,7 +29,6 @@ const DEFAULT_INTERVAL_MS = 1500;
const TIMEOUT_DISABLED_PREF = "browser.sessionstore.debug.no_auto_updates";
const PREF_INTERVAL = "browser.sessionstore.interval";
-const PREF_SESSION_COLLECTION = "browser.sessionstore.platform_collection";
class Handler {
constructor(store) {
@@ -96,7 +95,7 @@ class StateChangeNotifier extends Handler {
/**
* @see nsIWebProgressListener.onStateChange
*/
- onStateChange(webProgress, request, stateFlags, status) {
+ onStateChange(webProgress, request, stateFlags) {
// Ignore state changes for subframes because we're only interested in the
// top-document starting or stopping its load.
if (!webProgress.isTopLevel || webProgress.DOMWindow != this.mm.content) {
@@ -206,7 +205,7 @@ class SessionHistoryListener extends Handler {
});
}
- handleEvent(event) {
+ handleEvent() {
this.collect();
}
@@ -218,30 +217,30 @@ class SessionHistoryListener extends Handler {
this.collect();
}
- OnHistoryNewEntry(newURI, oldIndex) {
+ OnHistoryNewEntry() {
// We ought to collect the previously current entry as well, see bug 1350567.
// TODO: Reenable partial history collection for performance
// this.collectFrom(oldIndex);
this.collect();
}
- OnHistoryGotoIndex(index, gotoURI) {
+ OnHistoryGotoIndex() {
// We ought to collect the previously current entry as well, see bug 1350567.
// TODO: Reenable partial history collection for performance
// this.collectFrom(LAST_INDEX);
this.collect();
}
- OnHistoryPurge(numEntries) {
+ OnHistoryPurge() {
this.collect();
}
- OnHistoryReload(reloadURI, reloadFlags) {
+ OnHistoryReload() {
this.collect();
return true;
}
- OnHistoryReplaceEntry(index) {
+ OnHistoryReplaceEntry() {
this.collect();
}
}
@@ -607,7 +606,7 @@ class SessionStateAggregator extends GeckoViewChildModule {
this.messageQueue,
];
- if (!Services.prefs.getBoolPref(PREF_SESSION_COLLECTION, false)) {
+ if (!Services.appinfo.sessionStorePlatformCollection) {
this.handlers.push(
new FormDataListener(this),
new ScrollPositionListener(this)
diff --git a/mobile/android/chrome/geckoview/config.js b/mobile/android/chrome/geckoview/config.js
index 1cf92416ac..9b1226a330 100644
--- a/mobile/android/chrome/geckoview/config.js
+++ b/mobile/android/chrome/geckoview/config.js
@@ -147,7 +147,7 @@ var NewPrefDialog = {
// New prefs create dialog only allows creating a non-existing preference, doesn't allow for
// Changing an existing one on-the-fly, tap existing/displayed line item pref for that
- create: function AC_create(aEvent) {
+ create: function AC_create() {
if (this._positiveButton.getAttribute("disabled") == "true") {
return;
}
@@ -342,7 +342,7 @@ var AboutConfig = {
},
// If scrolling at the bottom, maybe add some more entries
- onScroll: function AC_onScroll(aEvent) {
+ onScroll: function AC_onScroll() {
if (
this._prefsContainer.scrollHeight -
(window.pageYOffset + window.innerHeight) <
diff --git a/mobile/android/chrome/geckoview/geckoview.js b/mobile/android/chrome/geckoview/geckoview.js
index 6dc5ed4610..dc7ceab7f8 100644
--- a/mobile/android/chrome/geckoview/geckoview.js
+++ b/mobile/android/chrome/geckoview/geckoview.js
@@ -255,7 +255,7 @@ var ModuleManager = {
this._moduleByActorName[aActorName].receiveMessage(aMessage);
},
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent ${aEvent} ${aData}`;
switch (aEvent) {
case "GeckoView:UpdateModuleState": {
@@ -865,11 +865,11 @@ function startup() {
ModuleManager.afterBrowserRemotenessChange(switchId);
}
- browser.addEventListener("WillChangeBrowserRemoteness", event =>
+ browser.addEventListener("WillChangeBrowserRemoteness", () =>
ModuleManager.willChangeBrowserRemoteness()
);
- browser.addEventListener("DidChangeBrowserRemoteness", event =>
+ browser.addEventListener("DidChangeBrowserRemoteness", () =>
ModuleManager.didChangeBrowserRemoteness()
);
diff --git a/mobile/android/components/extensions/ext-android.js b/mobile/android/components/extensions/ext-android.js
index b53c390f36..2576a42ba5 100644
--- a/mobile/android/components/extensions/ext-android.js
+++ b/mobile/android/components/extensions/ext-android.js
@@ -197,7 +197,7 @@ global.makeGlobalEvent = function makeGlobalEvent(
name,
register: fire => {
const listener2 = {
- onEvent(event, data, callback) {
+ onEvent(event, data) {
listener(fire, data);
},
};
diff --git a/mobile/android/components/extensions/ext-browserAction.js b/mobile/android/components/extensions/ext-browserAction.js
index 3a91e913f9..de693274d6 100644
--- a/mobile/android/components/extensions/ext-browserAction.js
+++ b/mobile/android/components/extensions/ext-browserAction.js
@@ -28,7 +28,7 @@ const BROWSER_ACTION_PROPERTIES = [
class BrowserAction extends BrowserActionBase {
constructor(extension, clickDelegate) {
- const tabContext = new TabContext(tabId => this.getContextData(null));
+ const tabContext = new TabContext(() => this.getContextData(null));
super(tabContext, extension);
this.clickDelegate = clickDelegate;
this.helper = new ExtensionActionHelper({
@@ -86,7 +86,7 @@ this.browserAction = class extends ExtensionAPIPersistent {
return GeckoViewWebExtension.browserActions.get(extension);
}
- async onManifestEntry(entryName) {
+ async onManifestEntry() {
const { extension } = this;
this.action = new BrowserAction(extension, this);
await this.action.loadIconData();
diff --git a/mobile/android/components/extensions/ext-downloads.js b/mobile/android/components/extensions/ext-downloads.js
index 6422440d54..1dd5b558e1 100644
--- a/mobile/android/components/extensions/ext-downloads.js
+++ b/mobile/android/components/extensions/ext-downloads.js
@@ -146,7 +146,7 @@ class DownloadItem {
this.downloads = class extends ExtensionAPIPersistent {
PERSISTENT_EVENTS = {
- onChanged({ fire }, params) {
+ onChanged({ fire }) {
const listener = (eventName, event) => {
const { delta, downloadItem } = event;
const { extension } = this;
@@ -248,23 +248,23 @@ this.downloads = class extends ExtensionAPIPersistent {
});
},
- removeFile(downloadId) {
+ removeFile() {
throw new ExtensionError("Not implemented");
},
- search(query) {
+ search() {
throw new ExtensionError("Not implemented");
},
- pause(downloadId) {
+ pause() {
throw new ExtensionError("Not implemented");
},
- resume(downloadId) {
+ resume() {
throw new ExtensionError("Not implemented");
},
- cancel(downloadId) {
+ cancel() {
throw new ExtensionError("Not implemented");
},
@@ -272,19 +272,19 @@ this.downloads = class extends ExtensionAPIPersistent {
throw new ExtensionError("Not implemented");
},
- erase(query) {
+ erase() {
throw new ExtensionError("Not implemented");
},
- open(downloadId) {
+ open() {
throw new ExtensionError("Not implemented");
},
- show(downloadId) {
+ show() {
throw new ExtensionError("Not implemented");
},
- getFileIcon(downloadId, options) {
+ getFileIcon() {
throw new ExtensionError("Not implemented");
},
diff --git a/mobile/android/components/extensions/ext-pageAction.js b/mobile/android/components/extensions/ext-pageAction.js
index 04973379f1..18eeb241b1 100644
--- a/mobile/android/components/extensions/ext-pageAction.js
+++ b/mobile/android/components/extensions/ext-pageAction.js
@@ -26,7 +26,7 @@ const PAGE_ACTION_PROPERTIES = [
class PageAction extends PageActionBase {
constructor(extension, clickDelegate) {
- const tabContext = new TabContext(tabId => this.getContextData(null));
+ const tabContext = new TabContext(() => this.getContextData(null));
super(tabContext, extension);
this.clickDelegate = clickDelegate;
this.helper = new ExtensionActionHelper({
@@ -80,7 +80,7 @@ this.pageAction = class extends ExtensionAPIPersistent {
return GeckoViewWebExtension.pageActions.get(extension);
}
- async onManifestEntry(entryName) {
+ async onManifestEntry() {
const { extension } = this;
const action = new PageAction(extension, this);
await action.loadIconData();
diff --git a/mobile/android/components/extensions/ext-tabs.js b/mobile/android/components/extensions/ext-tabs.js
index 88d3d9e83a..66c7417379 100644
--- a/mobile/android/components/extensions/ext-tabs.js
+++ b/mobile/android/components/extensions/ext-tabs.js
@@ -28,7 +28,7 @@ const tabListener = {
}
},
- onLocationChange(browser, webProgress, request, locationURI, flags) {
+ onLocationChange(browser, webProgress, request) {
if (webProgress.isTopLevel) {
const { tab } = browser.ownerGlobal;
@@ -103,7 +103,7 @@ this.tabs = class extends ExtensionAPIPersistent {
}
PERSISTENT_EVENTS = {
- onActivated({ fire, context }, params) {
+ onActivated({ fire, context }) {
const listener = (eventName, event) => {
const { windowId, tabId, isPrivate } = event;
if (isPrivate && !context.privateBrowsingAllowed) {
@@ -140,7 +140,7 @@ this.tabs = class extends ExtensionAPIPersistent {
});
},
}),
- onUpdated({ fire }, params) {
+ onUpdated({ fire }) {
const { tabManager } = this.extension;
const restricted = ["url", "favIconUrl", "title"];
@@ -328,7 +328,7 @@ this.tabs = class extends ExtensionAPIPersistent {
onAttached: new EventManager({
context,
name: "tabs.onAttached",
- register: fire => {
+ register: () => {
return () => {};
},
}).api(),
@@ -336,7 +336,7 @@ this.tabs = class extends ExtensionAPIPersistent {
onDetached: new EventManager({
context,
name: "tabs.onDetached",
- register: fire => {
+ register: () => {
return () => {};
},
}).api(),
@@ -351,7 +351,7 @@ this.tabs = class extends ExtensionAPIPersistent {
onReplaced: new EventManager({
context,
name: "tabs.onReplaced",
- register: fire => {
+ register: () => {
return () => {};
},
}).api(),
@@ -359,7 +359,7 @@ this.tabs = class extends ExtensionAPIPersistent {
onMoved: new EventManager({
context,
name: "tabs.onMoved",
- register: fire => {
+ register: () => {
return () => {};
},
}).api(),
@@ -378,7 +378,6 @@ this.tabs = class extends ExtensionAPIPersistent {
index,
openInReaderMode,
pinned,
- title,
url,
} = {}) {
if (active === null) {
diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
index cd708d942a..19aaf07f92 100644
--- a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
@@ -106,7 +106,7 @@ add_task(async function testTabRemovalEvent() {
async function background() {
function awaitLoad(tabId) {
return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
+ browser.tabs.onUpdated.addListener(function listener(tabId_, changed) {
if (tabId == tabId_ && changed.status == "complete") {
browser.tabs.onUpdated.removeListener(listener);
resolve();
@@ -115,7 +115,7 @@ add_task(async function testTabRemovalEvent() {
});
}
- chrome.tabs.onRemoved.addListener((tabId, info) => {
+ chrome.tabs.onRemoved.addListener((tabId) => {
browser.test.log("Make sure the removed tab is not available in the tabs.query callback.");
chrome.tabs.query({}, tabs => {
for (const tab of tabs) {
diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html
index 09e42d73cf..ab722f48d7 100644
--- a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html
@@ -40,7 +40,7 @@ add_task(async function testExecuteScript() {
browser.tabs.executeScript({
file: "script.js",
code: "42",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected not to be able to execute a script with both file and code");
}, error => {
browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message),
@@ -99,7 +99,7 @@ add_task(async function testExecuteScript() {
browser.tabs.executeScript({
code: "window",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName");
@@ -109,7 +109,7 @@ add_task(async function testExecuteScript() {
browser.tabs.executeScript({
code: "Promise.resolve(window)",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName");
@@ -119,7 +119,7 @@ add_task(async function testExecuteScript() {
browser.tabs.executeScript({
file: "script3.js",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
const expected = /Script '.*script3.js' result is non-structured-clonable data/;
@@ -130,7 +130,7 @@ add_task(async function testExecuteScript() {
browser.tabs.executeScript({
frameId: Number.MAX_SAFE_INTEGER,
code: "42",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected error when specifying invalid frame ID");
}, error => {
browser.test.assertEq(
@@ -143,7 +143,7 @@ add_task(async function testExecuteScript() {
browser.tabs.create({url: "http://example.net/", active: false}).then(async tab => {
await browser.tabs.executeScript(tab.id, {
code: "42",
- }).then(result => {
+ }).then(() => {
browser.test.fail("Expected error when trying to execute on invalid domain");
}, error => {
browser.test.assertEq(`Missing host permission for the tab`,
diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html
index 8d96e79cc2..1ec815c8c7 100644
--- a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html
@@ -44,7 +44,7 @@ add_task(async function test_onUpdated() {
}
});
- browser.runtime.onMessage.addListener(async msg => {
+ browser.runtime.onMessage.addListener(async () => {
if (collectedSequence.length !== expectedSequence.length) {
browser.test.assertEq(
JSON.stringify(expectedSequence),
diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html
index 320ce4dde6..4709fbe31c 100644
--- a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html
@@ -31,7 +31,7 @@ add_task(async function tabsSendMessageReply() {
// eslint-disable-next-line prefer-const
let firstTab;
const promiseResponse = new Promise(resolve => {
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
+ browser.runtime.onMessage.addListener((msg, sender) => {
if (msg == "content-script-ready") {
const tabId = sender.tab.id;
@@ -170,7 +170,7 @@ add_task(async function tabsSendHidden() {
background: async function() {
let resolveContent;
- browser.runtime.onMessage.addListener((msg, sender) => {
+ browser.runtime.onMessage.addListener((msg) => {
if (msg[0] == "content-ready") {
resolveContent(msg[1]);
}
@@ -220,7 +220,7 @@ add_task(async function tabsSendHidden() {
// properties of the possibly-hidden content window.
const href = window.location.href;
- browser.runtime.onMessage.addListener((msg, sender) => {
+ browser.runtime.onMessage.addListener((msg) => {
browser.test.assertEq(href, msg, "Should be in the expected content window");
return Promise.resolve(href);
diff --git a/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js
index 3ba2e26139..43bc138e7f 100644
--- a/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js
+++ b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js
@@ -34,7 +34,7 @@ class EmbedderPort {
onPortDisconnect() {
Assert.ok(false, "onPortDisconnect not expected to be called");
}
- onPortMessage(holder) {
+ onPortMessage() {
Assert.ok(false, "onPortMessage not expected to be called");
}
triggerPortDisconnect() {
diff --git a/mobile/android/components/geckoview/FilePickerDelegate.sys.mjs b/mobile/android/components/geckoview/FilePickerDelegate.sys.mjs
index 3972017b40..52d1b93233 100644
--- a/mobile/android/components/geckoview/FilePickerDelegate.sys.mjs
+++ b/mobile/android/components/geckoview/FilePickerDelegate.sys.mjs
@@ -15,14 +15,14 @@ const { debug, warn } = GeckoViewUtils.initLogging("FilePickerDelegate");
export class FilePickerDelegate {
/* ---------- nsIFilePicker ---------- */
- init(aParent, aTitle, aMode) {
+ init(aBrowsingContext, aTitle, aMode) {
if (
aMode === Ci.nsIFilePicker.modeGetFolder ||
aMode === Ci.nsIFilePicker.modeSave
) {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
- this._prompt = new lazy.GeckoViewPrompter(aParent);
+ this._prompt = new lazy.GeckoViewPrompter(aBrowsingContext);
this._msg = {
type: "file",
title: aTitle,
diff --git a/mobile/android/components/geckoview/GeckoViewPrompter.sys.mjs b/mobile/android/components/geckoview/GeckoViewPrompter.sys.mjs
index f81c155678..5c4b91c2de 100644
--- a/mobile/android/components/geckoview/GeckoViewPrompter.sys.mjs
+++ b/mobile/android/components/geckoview/GeckoViewPrompter.sys.mjs
@@ -140,7 +140,7 @@ export class GeckoViewPrompter {
// Spin this thread while we wait for a result
Services.tm.spinEventLoopUntil(
- "GeckoViewPrompter.jsm:showPrompt",
+ "GeckoViewPrompter.sys.mjs:showPrompt",
() => this._domWin.closed || result !== undefined
);
} finally {
diff --git a/mobile/android/components/geckoview/GeckoViewPush.sys.mjs b/mobile/android/components/geckoview/GeckoViewPush.sys.mjs
index d6625942e8..ee315b850f 100644
--- a/mobile/android/components/geckoview/GeckoViewPush.sys.mjs
+++ b/mobile/android/components/geckoview/GeckoViewPush.sys.mjs
@@ -22,7 +22,6 @@ const OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED = "push-subscription-modified";
function createSubscription({
scope,
- principal,
browserPublicKey,
authSecret,
endpoint,
@@ -59,7 +58,7 @@ export class PushService {
// nsIObserver methods
- observe(subject, topic, data) {}
+ observe() {}
// nsIPushService methods
@@ -151,13 +150,13 @@ export class PushService {
// nsIPushQuotaManager methods
- notificationForOriginShown(origin) {}
+ notificationForOriginShown() {}
- notificationForOriginClosed(origin) {}
+ notificationForOriginClosed() {}
// nsIPushErrorReporter methods
- reportDeliveryError(messageId, reason) {}
+ reportDeliveryError() {}
}
PushService.prototype.classID = Components.ID(
diff --git a/mobile/android/components/geckoview/GeckoViewStartup.sys.mjs b/mobile/android/components/geckoview/GeckoViewStartup.sys.mjs
index 734db47887..2a5b0beb4d 100644
--- a/mobile/android/components/geckoview/GeckoViewStartup.sys.mjs
+++ b/mobile/android/components/geckoview/GeckoViewStartup.sys.mjs
@@ -95,7 +95,7 @@ const JSWINDOWACTORS = {
export class GeckoViewStartup {
/* ---------- nsIObserver ---------- */
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe: ${aTopic}`;
switch (aTopic) {
case "content-process-ready-for-script":
@@ -284,7 +284,7 @@ export class GeckoViewStartup {
}
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent ${aEvent}`;
switch (aEvent) {
diff --git a/mobile/android/components/geckoview/LoginStorageDelegate.sys.mjs b/mobile/android/components/geckoview/LoginStorageDelegate.sys.mjs
index 28916917ca..3c6d264069 100644
--- a/mobile/android/components/geckoview/LoginStorageDelegate.sys.mjs
+++ b/mobile/android/components/geckoview/LoginStorageDelegate.sys.mjs
@@ -38,12 +38,7 @@ export class LoginStorageDelegate {
};
}
- promptToSavePassword(
- aBrowser,
- aLogin,
- dismissed = false,
- notifySaved = false
- ) {
+ promptToSavePassword(aBrowser, aLogin, dismissed = false) {
const prompt = new lazy.GeckoViewPrompter(aBrowser.ownerGlobal);
prompt.asyncShowPrompt(
this._createMessage({ dismissed }, [
@@ -75,7 +70,7 @@ export class LoginStorageDelegate {
aOldLogin,
aNewLogin,
dismissed = false,
- notifySaved = false,
+ notifySaved,
autoSavedLoginGuid = ""
) {
const newLogin = lazy.LoginEntry.fromLoginInfo(aOldLogin || aNewLogin);
diff --git a/mobile/android/docs/geckoview/design/priority-hint.rst b/mobile/android/docs/geckoview/design/priority-hint.rst
index 4a915bb7ed..d7250e60e8 100644
--- a/mobile/android/docs/geckoview/design/priority-hint.rst
+++ b/mobile/android/docs/geckoview/design/priority-hint.rst
@@ -47,7 +47,7 @@ Specified and active tabs would be ``PRIORITY_HIGH``. The default would be
public void setPriorityHint(final @Priority int priorityHint)
-Listeners in ``GeckoViewContent.jsm`` will set
+Listeners in ``GeckoViewContent.sys.mjs`` will set
``this.browser.frameLoader.remoteTab.priorityHint`` to the boolean passed in.
.. code:: java
diff --git a/mobile/android/docs/geckoview/design/save-to-pdf.rst b/mobile/android/docs/geckoview/design/save-to-pdf.rst
index fc4edc6310..63473f5ed9 100644
--- a/mobile/android/docs/geckoview/design/save-to-pdf.rst
+++ b/mobile/android/docs/geckoview/design/save-to-pdf.rst
@@ -40,12 +40,12 @@ What
----
This work will add a method to ``GeckoSession`` called ``savePdf`` for
-embedders to use, which will communicate with a new ``GeckoViewPdf.jsm`` to
+embedders to use, which will communicate with a new ``GeckoViewPdf.sys.mjs`` to
create the PDF file. When the document is available, the
``GeckoViewPdfController`` will notify the
``ContentDelegate.onExternalResponse`` with the downloadable document.
-- ``GeckoViewPdf.jsm`` - JavaScript implementation that converts the content to
+- ``GeckoViewPdf.sys.mjs`` - JavaScript implementation that converts the content to
a PDF and saves the file, also responds to messaging from
``GeckoViewPdfController``.
- ``GeckoViewPdfController.java`` - The Controller coordinates between the Java
@@ -72,8 +72,8 @@ GeckoSession.java
}
-GeckoViewPdf.jsm
-^^^^^^^^^^^^^^^^
+GeckoViewPdf.sys.mjs
+^^^^^^^^^^^^^^^^^^^^
.. code:: java
this.registerListener([
@@ -92,7 +92,7 @@ GeckoViewPdf.jsm
}
async saveToPDF() {
- // Reference: https://searchfox.org/mozilla-central/source/remote/cdp/domains/parent/Page.jsm#519
+ // Reference: https://searchfox.org/mozilla-central/source/remote/cdp/domains/parent/Page.sys.mjs#519
}
@@ -183,7 +183,7 @@ geckoview.js
{
name: "GeckoViewPdf",
onInit: {
- resource: "resource://gre/modules/GeckoViewPdf.jsm",
+ resource: "resource://gre/modules/GeckoViewPdf.sys.mjs",
}
}
@@ -191,7 +191,7 @@ geckoview.js
Testing
-------
-- Tests for the jsm and java code will be covered by mochitests and junit.
+- Tests for the sys.mjs and java code will be covered by mochitests and junit.
- Make assertions to check that the text and images are in the finished PDF;
the PDF is a non-zero file size.
diff --git a/mobile/android/exoplayer2/build.gradle b/mobile/android/exoplayer2/build.gradle
index d67995650f..f4106a7591 100644
--- a/mobile/android/exoplayer2/build.gradle
+++ b/mobile/android/exoplayer2/build.gradle
@@ -34,6 +34,10 @@ android {
}
}
+ publishing {
+ singleVariant("debug")
+ }
+
namespace 'org.mozilla.geckoview.thirdparty'
}
@@ -106,5 +110,7 @@ publishing {
}
}
-sourceCompatibility = JavaVersion.VERSION_1_8
-targetCompatibility = JavaVersion.VERSION_1_8
+java {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+}
diff --git a/mobile/android/geckoview/api.txt b/mobile/android/geckoview/api.txt
index 86869c0abe..30c4d35585 100644
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -51,6 +51,7 @@ import java.lang.Boolean;
import java.lang.CharSequence;
import java.lang.Class;
import java.lang.Comparable;
+import java.lang.Deprecated;
import java.lang.Double;
import java.lang.Exception;
import java.lang.Float;
@@ -85,6 +86,7 @@ import org.mozilla.geckoview.CompositorController;
import org.mozilla.geckoview.ContentBlocking;
import org.mozilla.geckoview.ContentBlockingController;
import org.mozilla.geckoview.CrashHandler;
+import org.mozilla.geckoview.DeprecationSchedule;
import org.mozilla.geckoview.ExperimentDelegate;
import org.mozilla.geckoview.GeckoDisplay;
import org.mozilla.geckoview.GeckoResult;
@@ -967,7 +969,7 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings.Builder preferredColorScheme(int);
method @NonNull public GeckoRuntimeSettings.Builder remoteDebuggingEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder screenSizeOverride(int, int);
- method @NonNull public GeckoRuntimeSettings.Builder telemetryDelegate(@NonNull RuntimeTelemetry.Delegate);
+ method @Deprecated @DeprecationSchedule(id="geckoview-gvst",version=127) @NonNull public GeckoRuntimeSettings.Builder telemetryDelegate(@NonNull RuntimeTelemetry.Delegate);
method @NonNull public GeckoRuntimeSettings.Builder translationsOfferPopup(boolean);
method @NonNull public GeckoRuntimeSettings.Builder trustedRecursiveResolverMode(int);
method @NonNull public GeckoRuntimeSettings.Builder trustedRecursiveResolverUri(@NonNull String);
@@ -1262,7 +1264,8 @@ package org.mozilla.geckoview {
method @UiThread default public void onCanGoForward(@NonNull GeckoSession, boolean);
method @Nullable @UiThread default public GeckoResult<String> onLoadError(@NonNull GeckoSession, @Nullable String, @NonNull WebRequestError);
method @Nullable @UiThread default public GeckoResult<AllowOrDeny> onLoadRequest(@NonNull GeckoSession, @NonNull GeckoSession.NavigationDelegate.LoadRequest);
- method @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>);
+ method @Deprecated @DeprecationSchedule(id="geckoview-onlocationchange",version=127) @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>);
+ method @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>, @NonNull Boolean);
method @Nullable @UiThread default public GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession, @NonNull String);
method @Nullable @UiThread default public GeckoResult<AllowOrDeny> onSubframeLoadRequest(@NonNull GeckoSession, @NonNull GeckoSession.NavigationDelegate.LoadRequest);
field public static final int LOAD_REQUEST_IS_REDIRECT = 8388608;
@@ -2674,12 +2677,16 @@ package org.mozilla.geckoview {
field @Nullable public final String downloadUrl;
field public final boolean enabled;
field @Nullable public final String fullDescription;
+ field @NonNull public final String[] grantedOptionalOrigins;
+ field @NonNull public final String[] grantedOptionalPermissions;
field @Nullable public final String homepageUrl;
field @NonNull public final Image icon;
field @Nullable public final String incognito;
field public final boolean isRecommended;
field @Nullable public final String name;
field public final boolean openOptionsPageInTab;
+ field @NonNull public final String[] optionalOrigins;
+ field @NonNull public final String[] optionalPermissions;
field @Nullable public final String optionsPageUrl;
field @NonNull public final String[] origins;
field @NonNull public final String[] permissions;
diff --git a/mobile/android/geckoview/build.gradle b/mobile/android/geckoview/build.gradle
index 32224dd5a2..6e5826655d 100644
--- a/mobile/android/geckoview/build.gradle
+++ b/mobile/android/geckoview/build.gradle
@@ -155,6 +155,10 @@ android {
aidl = true
}
+ publishing {
+ singleVariant('withGeckoBinariesDebug')
+ }
+
namespace 'org.mozilla.geckoview'
}
@@ -229,7 +233,7 @@ dependencies {
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "com.google.android.gms:play-services-fido:20.0.1"
- implementation "org.yaml:snakeyaml:2.0"
+ implementation "org.yaml:snakeyaml:2.2"
implementation "androidx.lifecycle:lifecycle-common:2.6.1"
implementation "androidx.lifecycle:lifecycle-process:2.6.1"
@@ -514,7 +518,7 @@ android.libraryVariants.all configureVariantDebugLevel
// be somewhere where the Android plugin is available so that we can fish the
// path to "android.jar".
task("generateSDKBindings", type: JavaExec) {
- classpath project(':annotations').jar.archivePath
+ classpath project(':annotations').jar.archiveFile
classpath project(':annotations').compileJava.classpath
classpath project(':annotations').sourceSets.main.runtimeClasspath
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-browser-action.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-browser-action.js
index cde31235ac..421859dfa2 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-browser-action.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-browser-action.js
@@ -1,7 +1,7 @@
window.addEventListener("DOMContentLoaded", init);
function init() {
- document.body.addEventListener("click", event => {
+ document.body.addEventListener("click", () => {
browser.browserAction.openPopup();
});
}
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-page-action.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-page-action.js
index f16d96333f..6e38fc7858 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-page-action.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/actions/test-open-popup-page-action.js
@@ -1,7 +1,7 @@
window.addEventListener("DOMContentLoaded", init);
function init() {
- document.body.addEventListener("click", event => {
+ document.body.addEventListener("click", () => {
browser.pageAction.openPopup();
});
}
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/borderify.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/borderify.js
new file mode 100644
index 0000000000..9c3728b381
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/borderify.js
@@ -0,0 +1 @@
+document.body.style.border = "5px solid red";
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/border-48.png b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/border-48.png
new file mode 100644
index 0000000000..90687de26d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/border-48.png
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/icon.svg b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/icon.svg
new file mode 100644
index 0000000000..dd1fae7d15
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/icons/icon.svg
@@ -0,0 +1 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 500 500" height="500px" id="Layer_1" version="1.1" viewBox="0 0 500 500" width="500px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path clip-rule="evenodd" d="M131.889,150.061v63.597h-27.256 c-20.079,0-36.343,16.263-36.343,36.342v181.711c0,20.078,16.264,36.34,36.343,36.34h290.734c20.078,0,36.345-16.262,36.345-36.34 V250c0-20.079-16.267-36.342-36.345-36.342h-27.254v-63.597c0-65.232-52.882-118.111-118.112-118.111 S131.889,84.828,131.889,150.061z M177.317,213.658v-63.597c0-40.157,32.525-72.685,72.683-72.685 c40.158,0,72.685,32.528,72.685,72.685v63.597H177.317z M213.658,313.599c0-20.078,16.263-36.341,36.342-36.341 s36.341,16.263,36.341,36.341c0,12.812-6.634,24.079-16.625,30.529c0,0,3.55,21.446,7.542,46.699 c0,7.538-6.087,13.625-13.629,13.625h-27.258c-7.541,0-13.627-6.087-13.627-13.625l7.542-46.699 C220.294,337.678,213.658,326.41,213.658,313.599z" fill="#010101" fill-rule="evenodd"/></svg> \ No newline at end of file
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/manifest.json b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/manifest.json
new file mode 100644
index 0000000000..f1dbe5fe71
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify-mv3/manifest.json
@@ -0,0 +1,26 @@
+{
+ "manifest_version": 3,
+ "name": "Borderify",
+ "version": "1.0",
+ "description": "Adds a red border to all webpages matching example.com.",
+ "browser_specific_settings": {
+ "gecko": {
+ "id": "borderify@tests.mozilla.org"
+ }
+ },
+ "icons": {
+ "48": "icons/border-48.png"
+ },
+ "content_scripts": [
+ {
+ "matches": ["*://*.example.com/*"],
+ "js": ["borderify.js"]
+ }
+ ],
+ "options_ui": {
+ "page": "dummy.html"
+ },
+ "granted_host_permissions": true,
+ "optional_permissions": ["clipboardRead", "*://opt-host-perm.example.com/*"],
+ "host_permissions": ["*://host-perm.example.com/*"]
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify/manifest.json b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify/manifest.json
index 4e3daf6708..4ea4eb093e 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify/manifest.json
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/borderify/manifest.json
@@ -19,5 +19,6 @@
],
"options_ui": {
"page": "dummy.html"
- }
+ },
+ "optional_permissions": ["clipboardRead", "*://developer.mozilla.org/*"]
}
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/clickToRequestPermission.html b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/clickToRequestPermission.html
new file mode 100644
index 0000000000..e6ddcb8c8d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/clickToRequestPermission.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="initial-scale=1.0" />
+ <script type="text/javascript" src="request-permission.js"></script>
+ </head>
+ <body style="height: 100%">
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/manifest.json b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/manifest.json
new file mode 100644
index 0000000000..0644eb637f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/manifest.json
@@ -0,0 +1,14 @@
+{
+ "manifest_version": 3,
+ "name": "optional-permission-request",
+ "browser_specific_settings": {
+ "gecko": {
+ "id": "optional-permission-request@example.com"
+ }
+ },
+ "version": "1.0",
+ "description": "Request optional extension permissions.",
+ "permissions": ["nativeMessaging", "geckoViewAddons"],
+ "granted_host_permissions": true,
+ "optional_permissions": ["geolocation", "*://example.com/*", "activeTab"]
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/request-permission.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/request-permission.js
new file mode 100644
index 0000000000..bae3ceea6f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/optional-permission-request/request-permission.js
@@ -0,0 +1,10 @@
+window.onload = () => {
+ document.body.addEventListener("click", async () => {
+ const perms = {
+ permissions: ["activeTab"],
+ origins: ["*://example.com/*"],
+ };
+ const response = await browser.permissions.request(perms);
+ browser.runtime.sendNativeMessage("browser", `${response}`);
+ });
+};
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/redirect-to-android-resource/background.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/redirect-to-android-resource/background.js
index fdf088a505..e77d482e14 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/redirect-to-android-resource/background.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/redirect-to-android-resource/background.js
@@ -2,7 +2,7 @@
function setupRedirect(fromUrl, redirectUrl) {
browser.webRequest.onBeforeRequest.addListener(
- details => {
+ () => {
console.log(`Extension redirects from ${fromUrl} to ${redirectUrl}`);
return { redirectUrl };
},
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
index 18e047ca1a..f47f42d12e 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
@@ -30,7 +30,7 @@ function connectNativePort() {
}
});
- function sendResponse(id, response, exception) {
+ function sendResponse(id, response) {
Promise.resolve(response).then(
value => sendSyncResponse(id, value),
reason => sendSyncResponse(id, null, reason)
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/update-postpone-1/background.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/update-postpone-1/background.js
index a301506ca7..8266ad8258 100644
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/update-postpone-1/background.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/update-postpone-1/background.js
@@ -1,3 +1,3 @@
-browser.runtime.onUpdateAvailable.addListener(details => {
+browser.runtime.onUpdateAvailable.addListener(() => {
// Do nothing, this is just here to prevent auto update.
});
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/clickToReplace.html b/mobile/android/geckoview/src/androidTest/assets/www/clickToReplace.html
new file mode 100644
index 0000000000..6d583586f1
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/clickToReplace.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="initial-scale=1.0" />
+ </head>
+ <body style="height: 100%" onclick="window.location.replace('replacedUrl')">
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html
index 9849747a41..950e48129e 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html
@@ -8,7 +8,7 @@
<video id="video" controls preload></video>
</body>
<script>
- window.addEventListener("DOMContentLoaded", function (e) {
+ window.addEventListener("DOMContentLoaded", function () {
const video = document.getElementById("video");
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html
index 5ebc2bddba..175d14bddf 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html
@@ -8,7 +8,7 @@
<div id="image_container"></div>
</body>
<script>
- window.addEventListener("DOMContentLoaded", function (e) {
+ window.addEventListener("DOMContentLoaded", function () {
const svg = `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" stroke="orange" fill="transparent" stroke-width="5"/>
</svg>`;
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms.html b/mobile/android/geckoview/src/androidTest/assets/www/forms.html
index 06c2ed64db..5d3ce9345e 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/forms.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms.html
@@ -24,7 +24,7 @@
<iframe id="iframe"></iframe>
</body>
<script>
- addEventListener("load", function (e) {
+ addEventListener("load", function () {
if (window.parent === window) {
document.getElementById("iframe").contentWindow.location.href =
window.location.href;
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html b/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html
index d1a421c0a3..4fadaf063f 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html
@@ -70,7 +70,7 @@
.getElementById("three")
.scrollTo({ top: 200, behavior: "instant" });
- document.getElementById("four").addEventListener("touchstart", e => {
+ document.getElementById("four").addEventListener("touchstart", () => {
console.log("not preventing default");
});
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js b/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
index 2e51383205..5c0acdb981 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
+++ b/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
@@ -22,7 +22,7 @@ self.addEventListener("push", async function (e) {
} catch (e) {}
});
-self.addEventListener("pushsubscriptionchange", async function (e) {
+self.addEventListener("pushsubscriptionchange", async function () {
const clients = await self.clients.matchAll();
clients.forEach(function (client) {
client.postMessage({ type: "pushsubscriptionchange" });
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/scroll.html b/mobile/android/geckoview/src/androidTest/assets/www/scroll.html
index e906e45686..ecc35e690c 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/scroll.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/scroll.html
@@ -51,7 +51,7 @@
e.preventDefault();
});
- document.getElementById("three").addEventListener("touchstart", e => {
+ document.getElementById("three").addEventListener("touchstart", () => {
console.log("not preventing default");
});
</script>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html b/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html
index 62266b6ef7..bf315cfb7e 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html
@@ -41,7 +41,7 @@
}
div.style.touchAction = searchParams.get("touch-action");
if (searchParams.has("event")) {
- div.addEventListener("touchstart", e => {});
+ div.addEventListener("touchstart", () => {});
}
</script>
</body>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch.html b/mobile/android/geckoview/src/androidTest/assets/www/touch.html
index ba3bc098a9..6852a0f4fe 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/touch.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch.html
@@ -50,7 +50,7 @@
e.preventDefault();
});
- document.getElementById("three").addEventListener("touchstart", e => {
+ document.getElementById("three").addEventListener("touchstart", () => {
console.log("not preventing default");
});
</script>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html b/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html
index 9ee1f461a7..42d1787ef1 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html
@@ -31,7 +31,7 @@
<div id="one"></div>
<div id="two"></div>
<script>
- document.getElementById("two").addEventListener("touchstart", e => {});
+ document.getElementById("two").addEventListener("touchstart", () => {});
</script>
</body>
</html>
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt
index fbfe2fe46d..dddba77768 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt
@@ -2407,7 +2407,7 @@ class AutocompleteTest : BaseSessionTest() {
"Hint should match",
option.hint,
equalTo(LoginSaveOption.Hint.GENERATED))
- */
+ */
assertThat(
"Password should not be empty",
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
index 655db7248f..d57cd8f157 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -36,6 +36,7 @@ open class BaseSessionTest(
const val RESUBMIT_CONFIRM = "/assets/www/resubmit.html"
const val BEFORE_UNLOAD = "/assets/www/beforeunload.html"
const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
+ const val CLICK_TO_REPLACE_HTML_PATH = "/assets/www/clickToReplace.html"
const val CLIPBOARD_READ_HTML_PATH = "/assets/www/clipboard_read.html"
const val CONTENT_CRASH_URL = "about:crashcontent"
const val DND_HTML_PATH = "/assets/www/dnd.html"
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoAppShellTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoAppShellTest.kt
index c05820012d..75204a2f5d 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoAppShellTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoAppShellTest.kt
@@ -86,6 +86,7 @@ class GeckoAppShellTest : BaseSessionTest() {
// This is waiting and holding the test harness open while Android Lifecycle events complete
mainSession.waitUntilCalled(object : GeckoSession.ContentDelegate, GeckoSession.NavigationDelegate {
@GeckoSessionTestRule.AssertCalled(count = 2)
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
index d6380bf5bf..2ec305f913 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
@@ -1115,6 +1115,7 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
@NullDelegate(NavigationDelegate::class)
fun delegateDuringNextWait_throwOnNullDelegate() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
}
})
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeolocationTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeolocationTest.kt
index 1bb568123c..4deac5fb66 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeolocationTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeolocationTest.kt
@@ -72,8 +72,7 @@ class GeolocationTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: GeckoSession.PermissionDelegate.ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
override fun onAndroidPermissionsRequest(
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/HistoryDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/HistoryDelegateTest.kt
index 370594a93f..2d2f4bb4af 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/HistoryDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/HistoryDelegateTest.kt
@@ -250,6 +250,11 @@ class HistoryDelegateTest : BaseSessionTest() {
}
@Test fun onHistoryStateChangeSavingState() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocaleTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocaleTest.kt
index 69deac1c89..608681d7d9 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocaleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocaleTest.kt
@@ -40,4 +40,16 @@ class LocaleTest : BaseSessionTest() {
equalTo(listOf("en-GB", "en-US", "en-FR")),
)
}
+
+ @Test
+ fun acceptLangaugeFormat() {
+ // No way to override default language settings from unit test.
+ // So we only test this on current settings.
+
+ val intlAcceptLanauge = "intl.accept_languages"
+ val prefValue = (sessionRule.getPrefs(intlAcceptLanauge)[0] as String).split(",")
+ for (value in prefValue) {
+ assertThat("Accept-Lanauge format should be language or language-region", value.filter { it == '-' }.count(), lessThanOrEqualTo(1))
+ }
+ }
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
index aab32cd01d..839ac4b468 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt
@@ -67,8 +67,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"URI should be " + testLoader.getUri(),
request.uri,
@@ -123,6 +122,7 @@ class NavigationDelegateTest : BaseSessionTest() {
if (errorPageUrl != null) {
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@@ -492,8 +492,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("The URLs must match", request.uri, equalTo(forEachCall(uri, httpsUri)))
return null
}
@@ -552,8 +551,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("The URLs must match", request.uri, equalTo(forEachCall(uri, httpsUri)))
return null
}
@@ -593,6 +591,7 @@ class NavigationDelegateTest : BaseSessionTest() {
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@@ -611,8 +610,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("The URLs must match", request.uri, equalTo(forEachCall(uri, httpsUri)))
return null
}
@@ -646,6 +644,7 @@ class NavigationDelegateTest : BaseSessionTest() {
// No good way to wait for loading about:blank error page. Use onLocaitonChange etc.
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@@ -665,8 +664,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
// We set http scheme only in case it's not iFrame
assertThat("The URLs must match", request.uri, equalTo(uri))
return null
@@ -717,8 +715,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"URI should be HTTP then redirected to HTTPS",
request.uri,
@@ -774,8 +771,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onSubframeLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("URI should not be null", request.uri, notNullValue())
assertThat("URI should match", request.uri, endsWith(iframeUri))
return null
@@ -862,8 +858,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("Session should not be null", session, notNullValue())
assertThat("URI should not be null", request.uri, notNullValue())
assertThat(
@@ -913,8 +908,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("Session should not be null", session, notNullValue())
assertThat("App requested this load", request.isDirectNavigation, equalTo(true))
assertThat("URI should not be null", request.uri, notNullValue())
@@ -927,8 +921,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onSubframeLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("Session should not be null", session, notNullValue())
assertThat("App did not request this load", request.isDirectNavigation, equalTo(false))
assertThat("URI should not be null", request.uri, notNullValue())
@@ -960,8 +953,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("Session should not be null", session, notNullValue())
assertThat("URI should not be null", request.uri, notNullValue())
assertThat(
@@ -1023,8 +1015,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("URL should match", request.uri, equalTo(forEachCall(uri, redirectUri)))
assertThat(
"From app should be correct",
@@ -1447,8 +1438,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("Session should not be null", session, notNullValue())
assertThat("URI should not be null", request.uri, notNullValue())
assertThat("URI should match", request.uri, endsWith(HELLO_HTML_PATH))
@@ -1478,10 +1468,12 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("Session should not be null", session, notNullValue())
assertThat("URL should not be null", url, notNullValue())
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@@ -1514,8 +1506,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match the provided data URL", url, equalTo(dataUrl))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@@ -1542,6 +1536,7 @@ class NavigationDelegateTest : BaseSessionTest() {
// Test that if we unset the navigation delegate during a load, the load still proceeds.
var onLocationCount = 0
mainSession.navigationDelegate = object : NavigationDelegate {
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@@ -1587,12 +1582,14 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat(
"URL should be a data URL",
url,
equalTo(createDataUri(dataString, mimeType)),
)
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@@ -1612,8 +1609,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should be a data URL", url, startsWith("data:"))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@@ -1641,8 +1640,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, equalTo(createDataUri(bytes, "text/html")))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@@ -1683,8 +1684,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, equalTo(createDataUri(bytes, mimeType)))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@@ -1714,8 +1717,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("URI should match", request.uri, endsWith(HELLO_HTML_PATH))
assertThat(
"Trigger URL should be null",
@@ -1740,8 +1742,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@@ -1774,8 +1778,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO2_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
@@ -1787,8 +1793,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Load should not be direct",
request.isDirectNavigation,
@@ -1802,8 +1807,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@@ -1830,8 +1837,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Load should not be direct",
request.isDirectNavigation,
@@ -1845,8 +1851,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO2_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@@ -1872,8 +1880,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
if (request.uri.endsWith(HELLO_HTML_PATH)) {
return GeckoResult.deny()
} else {
@@ -1913,8 +1920,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("URI should be correct", request.uri, endsWith(NEW_SESSION_CHILD_HTML_PATH))
assertThat(
"Trigger URL should match",
@@ -1969,8 +1975,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat("URI should be correct", request.uri, endsWith(NEW_SESSION_CHILD_HTML_PATH))
assertThat(
"Trigger URL should be null",
@@ -2080,8 +2085,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
// Pretend we handled the target="_blank" link click.
if (request.uri.endsWith(NEW_SESSION_CHILD_HTML_PATH)) {
return GeckoResult.deny()
@@ -2102,8 +2106,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"URI must match",
request.uri,
@@ -2151,8 +2154,7 @@ class NavigationDelegateTest : BaseSessionTest() {
mainSession.waitUntilCalled(object : NavigationDelegate {
@AssertCalled(count = 1, order = [1])
- override fun onLoadRequest(session: GeckoSession, request: LoadRequest):
- GeckoResult<AllowOrDeny>? {
+ override fun onLoadRequest(session: GeckoSession, request: LoadRequest): GeckoResult<AllowOrDeny>? {
assertThat(
"URL should be correct",
request.uri,
@@ -2172,8 +2174,7 @@ class NavigationDelegateTest : BaseSessionTest() {
}
@AssertCalled(count = 1, order = [2])
- override fun onNewSession(session: GeckoSession, uri: String):
- GeckoResult<GeckoSession>? {
+ override fun onNewSession(session: GeckoSession, uri: String): GeckoResult<GeckoSession>? {
assertThat("URL should be correct", uri, endsWith("form_blank.html?"))
return null
}
@@ -2621,6 +2622,7 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
currentUrl = url
}
@@ -2702,8 +2704,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Load should not be direct",
request.isDirectNavigation,
@@ -2717,8 +2718,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URI should match", url, endsWith("#test1"))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
@@ -2729,8 +2732,7 @@ class NavigationDelegateTest : BaseSessionTest() {
override fun onLoadRequest(
session: GeckoSession,
request: LoadRequest,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
return null
}
@@ -2739,13 +2741,20 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URI should match", url, endsWith("#test2"))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
}
@Test fun purgeHistory() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
@@ -2830,6 +2839,54 @@ class NavigationDelegateTest : BaseSessionTest() {
})
}
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun locationReplaceOnUserGesture() {
+ mainSession.loadUri("$TEST_ENDPOINT$CLICK_TO_REPLACE_HTML_PATH")
+ mainSession.waitForPageStop()
+
+ mainSession.synthesizeTap(50, 50)
+
+ sessionRule.waitUntilCalled(object : NavigationDelegate {
+ @AssertCalled(count = 1)
+ override fun onLocationChange(
+ session: GeckoSession,
+ url: String?,
+ perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
+ ) {
+ assertThat("Should have a user gesture", hasUserGesture, equalTo(true))
+ assertThat(
+ "Location should be replaced to replacedUrl",
+ url,
+ equalTo("replacedUrl"),
+ )
+ }
+ })
+ }
+
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun locationNotReplaceOnNoUserGesture() {
+ mainSession.loadUri("$TEST_ENDPOINT$HELLO_HTML_PATH")
+ sessionRule.waitForPageStop()
+
+ sessionRule.forCallbacksDuringWait(object : NavigationDelegate {
+ @AssertCalled(count = 1, order = [2])
+ override fun onLocationChange(
+ session: GeckoSession,
+ url: String?,
+ perms: MutableList<PermissionDelegate.ContentPermission>,
+ hasUserGesture: Boolean,
+ ) {
+ assertThat("Session should not be null", session, notNullValue())
+ assertThat("URL should not be null", url, notNullValue())
+ assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
+ assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
+ }
+ })
+ }
+
@Test fun loadAfterLoad() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 2)
@@ -3078,6 +3135,11 @@ class NavigationDelegateTest : BaseSessionTest() {
}
@Test fun goBackFromHistory() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
@@ -3119,6 +3181,7 @@ class NavigationDelegateTest : BaseSessionTest() {
var lastTitle: String? = ""
sessionRule.delegateDuringNextWait(object : NavigationDelegate, ContentDelegate {
@AssertCalled(count = 1)
+ @Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/OpenWindowTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/OpenWindowTest.kt
index 335535bbb4..b7aed020b4 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/OpenWindowTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/OpenWindowTest.kt
@@ -64,7 +64,7 @@ class OpenWindowTest : BaseSessionTest() {
@NullDelegate(ServiceWorkerDelegate::class)
fun openWindowNullDelegate() {
sessionRule.delegateUntilTestEnd(object : ContentDelegate, NavigationDelegate {
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
// we should not open the target url
assertThat("URL should notmatch", url, not(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@@ -76,7 +76,7 @@ class OpenWindowTest : BaseSessionTest() {
@Test
fun openWindowNullResult() {
sessionRule.delegateUntilTestEnd(object : ContentDelegate, NavigationDelegate {
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
// we should not open the target url
assertThat("URL should notmatch", url, not(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@@ -103,7 +103,7 @@ class OpenWindowTest : BaseSessionTest() {
openPageClickNotification()
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat("Should be on the main session", session, equalTo(mainSession))
assertThat("URL should match", url, equalTo(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@@ -130,7 +130,7 @@ class OpenWindowTest : BaseSessionTest() {
openPageClickNotification()
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat("Should be on the target session", session, equalTo(targetSession))
assertThat("URL should match", url, equalTo(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PdfCreationTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PdfCreationTest.kt
index 627c076fc4..de9f282484 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PdfCreationTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PdfCreationTest.kt
@@ -177,4 +177,16 @@ class PdfCreationTest : BaseSessionTest() {
}
}
}
+
+ @NullDelegate(Autofill.Delegate::class)
+ @Test
+ fun dontTryToOpenNullContent() {
+ // Bug 1881927.
+ assumeThat(sessionRule.env.isIsolatedProcess, equalTo(false))
+ activityRule.scenario.onActivity {
+ TestContentProvider.setNullTestData("application/pdf")
+ mainSession.loadUri("content://org.mozilla.geckoview.test.provider/pdf")
+ mainSession.waitForPageStop()
+ }
+ }
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt
index 9ab2d2515f..6b39d410eb 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt
@@ -214,8 +214,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -275,7 +274,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_GEOLOCATION &&
@@ -302,8 +301,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
return GeckoResult.fromValue(ContentPermission.VALUE_DENY)
}
@@ -342,7 +340,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_GEOLOCATION &&
@@ -462,6 +460,7 @@ class PermissionDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<ContentPermission>,
+ hasUserGesture: Boolean,
) {
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_TRACKING) {
@@ -501,6 +500,7 @@ class PermissionDelegateTest : BaseSessionTest() {
assertTrackingProtectionPermission(null)
mainSession.loadTestPath(HELLO_HTML_PATH)
+ mainSession.waitForPageStop()
assertTrackingProtectionPermission(ContentPermission.VALUE_DENY)
}
@@ -515,8 +515,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -551,7 +550,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -587,8 +586,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
return GeckoResult.fromValue(ContentPermission.VALUE_DENY)
}
})
@@ -617,7 +615,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -649,8 +647,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.waitUntilCalled(object : PermissionDelegate {
@AssertCalled(count = 2)
- override fun onContentPermissionRequest(session: GeckoSession, perm: ContentPermission):
- GeckoResult<Int> {
+ override fun onContentPermissionRequest(session: GeckoSession, perm: ContentPermission): GeckoResult<Int> {
val expectedType = if (sessionRule.currentCall.counter == 1) PermissionDelegate.PERMISSION_AUTOPLAY_AUDIBLE else PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE
assertThat("Type should match", perm.permission, equalTo(expectedType))
return GeckoResult.fromValue(ContentPermission.VALUE_DENY)
@@ -670,8 +667,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -707,7 +703,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -736,8 +732,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -777,7 +772,7 @@ class PermissionDelegateTest : BaseSessionTest() {
session2.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -805,8 +800,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -841,7 +835,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -876,8 +870,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -919,7 +912,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@@ -954,8 +947,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
@@ -1000,8 +992,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
return GeckoResult.fromValue(ContentPermission.VALUE_PROMPT)
}
})
@@ -1026,8 +1017,7 @@ class PermissionDelegateTest : BaseSessionTest() {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: ContentPermission,
- ):
- GeckoResult<Int> {
+ ): GeckoResult<Int> {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat(
"Type should match",
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
index 3097452da8..f8046ed2ed 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt
@@ -33,7 +33,7 @@ class ProgressDelegateTest : BaseSessionTest() {
ProgressDelegate,
NavigationDelegate {
@AssertCalled
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("LocationChange is called", url, endsWith(path))
}
@@ -448,6 +448,11 @@ class ProgressDelegateTest : BaseSessionTest() {
@WithDisplay(width = 400, height = 400)
@Test
fun saveAndRestoreStateNewSession() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
val helloUri = createTestUrl(HELLO_HTML_PATH)
@@ -467,6 +472,7 @@ class ProgressDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<ContentPermission>,
+ hasUserGesture: Boolean,
) {
assertThat("URI should match", url, equalTo(startUri))
}
@@ -487,7 +493,7 @@ class ProgressDelegateTest : BaseSessionTest() {
session.goBack()
session.waitUntilCalled(object : NavigationDelegate {
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("History should be preserved", url, equalTo(helloUri))
}
})
@@ -511,7 +517,7 @@ class ProgressDelegateTest : BaseSessionTest() {
sessionRule.forCallbacksDuringWait(object : NavigationDelegate {
@AssertCalled
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("URI should match", url, equalTo(startUri))
}
})
@@ -532,6 +538,11 @@ class ProgressDelegateTest : BaseSessionTest() {
@WithDisplay(width = 400, height = 400)
@Test
fun flushSessionState() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
val startUri = createTestUrl(SAVE_STATE_PATH)
@@ -568,6 +579,11 @@ class ProgressDelegateTest : BaseSessionTest() {
@NullDelegate(GeckoSession.HistoryDelegate::class)
@Test
fun noHistoryDelegateOnSessionStateChange() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
mainSession.loadTestPath(HELLO_HTML_PATH)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/RuntimeSettingsTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/RuntimeSettingsTest.kt
index 6504af8a4c..2b690726f3 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/RuntimeSettingsTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/RuntimeSettingsTest.kt
@@ -277,8 +277,7 @@ class RuntimeSettingsTest : BaseSessionTest() {
mainSession.loadUri("about:config")
mainSession.waitUntilCalled(object : NavigationDelegate {
@AssertCalled
- override fun onLoadError(session: GeckoSession, uri: String?, error: WebRequestError):
- GeckoResult<String>? {
+ override fun onLoadError(session: GeckoSession, uri: String?, error: WebRequestError): GeckoResult<String>? {
assertThat("about:config should not load.", uri, equalTo("about:config"))
return null
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ScreenshotTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ScreenshotTest.kt
index cee16f3f4c..f3141c661c 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ScreenshotTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ScreenshotTest.kt
@@ -203,6 +203,11 @@ class ScreenshotTest : BaseSessionTest() {
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun capturePixelsWhileSessionDeactivated() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH, SCREEN_HEIGHT)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt
index e5e8ec6ce2..d3e52cda6a 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt
@@ -393,8 +393,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onShowClipboardPermissionRequest(
session: GeckoSession,
perm: ClipboardPermission,
- ):
- GeckoResult<AllowOrDeny> {
+ ): GeckoResult<AllowOrDeny> {
assertThat(
"Type should match",
perm.type,
@@ -408,8 +407,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onAlertPrompt(
session: GeckoSession,
prompt: PromptDelegate.AlertPrompt,
- ):
- GeckoResult<PromptDelegate.PromptResponse> {
+ ): GeckoResult<PromptDelegate.PromptResponse> {
assertThat("Message should match", "allow", equalTo(prompt.message))
result.complete(null)
return GeckoResult.fromValue(prompt.dismiss())
@@ -440,8 +438,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onShowClipboardPermissionRequest(
session: GeckoSession,
perm: ClipboardPermission,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Type should match",
perm.type,
@@ -454,8 +451,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onAlertPrompt(
session: GeckoSession,
prompt: PromptDelegate.AlertPrompt,
- ):
- GeckoResult<PromptDelegate.PromptResponse> {
+ ): GeckoResult<PromptDelegate.PromptResponse> {
assertThat("Message should match", "deny", equalTo(prompt.message))
result.complete(null)
return GeckoResult.fromValue(prompt.dismiss())
@@ -486,8 +482,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onShowClipboardPermissionRequest(
session: GeckoSession,
perm: ClipboardPermission,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Type should match",
perm.type,
@@ -533,8 +528,7 @@ class SelectionActionDelegateTest : BaseSessionTest() {
override fun onShowClipboardPermissionRequest(
session: GeckoSession,
perm: ClipboardPermission,
- ):
- GeckoResult<AllowOrDeny>? {
+ ): GeckoResult<AllowOrDeny>? {
assertThat(
"Type should match",
perm.type,
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestContentProvider.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestContentProvider.java
index 787448a859..b0591b693e 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestContentProvider.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestContentProvider.java
@@ -18,6 +18,7 @@ public class TestContentProvider extends ContentProvider {
private static final String LOGTAG = "TestContentProvider";
private static byte[] sTestData;
private static String sMimeType;
+ private static boolean sAllowNullData = false;
@Override
public boolean onCreate() {
@@ -62,7 +63,10 @@ public class TestContentProvider extends ContentProvider {
public ParcelFileDescriptor openFile(final Uri uri, final String mode)
throws FileNotFoundException {
if (sTestData == null) {
- throw new FileNotFoundException("No test data for: " + uri);
+ if (!sAllowNullData) {
+ throw new FileNotFoundException("No test data for: " + uri);
+ }
+ return null;
}
ParcelFileDescriptor[] pipe = null;
@@ -98,6 +102,19 @@ public class TestContentProvider extends ContentProvider {
*/
public static void setTestData(final byte[] data, final String mimeType) {
sTestData = data;
+ sAllowNullData = false;
+ sMimeType = mimeType;
+ }
+
+ /**
+ * Set null that is used from content resolver but don't throw when calling openFile.
+ *
+ * @param data test data
+ * @param mimeType A mime type of test data.
+ */
+ public static void setNullTestData(final String mimeType) {
+ sTestData = null;
+ sAllowNullData = true;
sMimeType = mimeType;
}
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt
index 7e4015a246..ca21d0a61d 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt
@@ -537,7 +537,8 @@ class TextInputDelegateTest : BaseSessionTest() {
"Can commit text (select before)",
ic,
"foobarfoo",
- 5, /* checkGecko */
+ 5,
+ /* checkGecko */
false,
)
}
@@ -641,7 +642,8 @@ class TextInputDelegateTest : BaseSessionTest() {
"Can set new composing region text",
ic,
"frabar",
- 6, /* checkGecko */
+ 6,
+ /* checkGecko */
false,
)
@@ -826,7 +828,13 @@ class TextInputDelegateTest : BaseSessionTest() {
}.joinToString("")
setupContent(content)
val ic = mainSession.textInput.onCreateInputConnection(EditorInfo())!!
- assertText("Can set large initial text", ic, content, /* checkGecko */ false)
+ assertText(
+ "Can set large initial text",
+ ic,
+ content,
+ /* checkGecko */
+ false,
+ )
}
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N_MR1)
@@ -1279,6 +1287,25 @@ class TextInputDelegateTest : BaseSessionTest() {
assertText("commit abc", ic, "abc")
}
+ // Bug 1837931 - When 2nd commitText uses -1 as newCursorPosition into batch mode, text
+ // cannot insert correct position.
+ @WithDisplay(width = 512, height = 512)
+ // Child process updates require having a display.
+ @Test
+ fun inputConnection_multiple_commitText_into_batchEdit() {
+ setupContent("")
+ val ic = mainSession.textInput.onCreateInputConnection(EditorInfo())!!
+
+ // Emulate GBoard's InputConnection API calls
+ ic.beginBatchEdit()
+ ic.commitText("( ", 1)
+ ic.commitText(")", -1)
+ ic.endBatchEdit()
+ processChildEvents()
+
+ assertText("commit ()", ic, "( )")
+ }
+
// Bug 1593683 - Cursor is jumping when using the arrow keys in input field on GBoard
@WithDisplay(width = 512, height = 512)
// Child process updates require having a display.
@@ -1294,7 +1321,14 @@ class TextInputDelegateTest : BaseSessionTest() {
pressKey(ic, KeyEvent.KEYCODE_DPAD_LEFT)
pressKey(ic, KeyEvent.KEYCODE_DPAD_LEFT)
pressKey(ic, KeyEvent.KEYCODE_DPAD_LEFT)
- assertSelection("IME caret is moved to top", ic, 0, 0, /* checkGecko */ false)
+ assertSelection(
+ "IME caret is moved to top",
+ ic,
+ 0,
+ 0,
+ /* checkGecko */
+ false,
+ )
setComposingText(ic, "bar", 1)
finishComposingText(ic)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TrackingPermissionService.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TrackingPermissionService.java
index 141849589e..4b7bcabee5 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TrackingPermissionService.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TrackingPermissionService.java
@@ -36,7 +36,8 @@ public class TrackingPermissionService extends TestRuntimeService {
public void onLocationChange(
final @NonNull GeckoSession session,
final @Nullable String url,
- final @NonNull List<ContentPermission> perms) {
+ final @NonNull List<ContentPermission> perms,
+ final @NonNull Boolean hasUserGesture) {
for (ContentPermission perm : perms) {
if (perm.permission == PermissionDelegate.PERMISSION_TRACKING) {
mContentPermission = perm;
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/VideoCaptureTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/VideoCaptureTest.kt
new file mode 100644
index 0000000000..7e1f8b1275
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/VideoCaptureTest.kt
@@ -0,0 +1,58 @@
+package org.mozilla.geckoview.test
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.webrtc.CameraEnumerationAndroid.CaptureFormat
+import org.webrtc.CameraEnumerator
+import org.webrtc.CameraVideoCapturer
+import org.webrtc.CameraVideoCapturer.CameraEventsHandler
+import org.webrtc.videoengine.VideoCaptureAndroid
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class VideoCaptureTest {
+ // Always throw exception.
+ class BadCameraEnumerator : CameraEnumerator {
+ override fun getDeviceNames(): Array<String?>? {
+ throw java.lang.RuntimeException("")
+ }
+
+ override fun isFrontFacing(deviceName: String?): Boolean {
+ throw java.lang.RuntimeException("")
+ }
+
+ override fun isBackFacing(deviceName: String?): Boolean {
+ throw java.lang.RuntimeException("")
+ }
+
+ override fun isInfrared(deviceName: String?): Boolean {
+ throw java.lang.RuntimeException("")
+ }
+
+ override fun getSupportedFormats(deviceName: String?): List<CaptureFormat?>? {
+ throw java.lang.RuntimeException("")
+ }
+
+ override fun createCapturer(
+ deviceName: String?,
+ eventsHandler: CameraEventsHandler?,
+ ): CameraVideoCapturer? {
+ throw java.lang.RuntimeException("")
+ }
+ }
+
+ @Test
+ fun constructWithBadEnumerator() {
+ val ctr = VideoCaptureAndroid::class.java.getDeclaredConstructors()[0].apply { isAccessible = true }
+ val capture = ctr.newInstance(
+ InstrumentationRegistry.getInstrumentation().targetContext,
+ "my camera",
+ BadCameraEnumerator(),
+ ) as VideoCaptureAndroid
+ assertEquals(false, capture.canCapture())
+ }
+}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
index 126e52da34..702ba4d23b 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
@@ -7,6 +7,7 @@ package org.mozilla.geckoview.test
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers
import org.hamcrest.Matchers.greaterThan
import org.hamcrest.core.IsEqual.equalTo
import org.hamcrest.core.StringEndsWith.endsWith
@@ -90,6 +91,14 @@ class WebExtensionTest : BaseSessionTest() {
assertTrue(borderify.isBuiltIn)
+ assertArrayEquals(
+ arrayOf("*://developer.mozilla.org/*"),
+ borderify.metaData.optionalOrigins,
+ )
+ assertArrayEquals(
+ arrayOf("clipboardRead"),
+ borderify.metaData.optionalPermissions,
+ )
mainSession.reload()
sessionRule.waitForPageStop()
@@ -109,6 +118,156 @@ class WebExtensionTest : BaseSessionTest() {
assertBodyBorderEqualTo("")
}
+ @Test
+ fun verifyOptionalAndOriginsPermissionsMV3() {
+ mainSession.loadUri("https://example.com")
+ sessionRule.waitForPageStop()
+
+ // First let's check that the color of the border is empty before loading
+ // the WebExtension
+ assertBodyBorderEqualTo("")
+
+ // Load the WebExtension that will add a border to the body
+ val borderify = sessionRule.waitForResult(
+ controller.installBuiltIn(
+ "resource://android/assets/web_extensions/borderify-mv3/",
+ ),
+ )
+
+ assertArrayEquals(
+ arrayOf("clipboardRead"),
+ borderify.metaData.optionalPermissions,
+ )
+
+ val expectedOptionalOrigins = arrayOf(
+ "*://*.example.com/*",
+ "*://opt-host-perm.example.com/*",
+ "*://host-perm.example.com/*",
+ )
+
+ expectedOptionalOrigins.sort()
+ borderify.metaData.optionalOrigins.sort()
+
+ assertArrayEquals(
+ expectedOptionalOrigins,
+ borderify.metaData.optionalOrigins,
+ )
+
+ mainSession.reload()
+ sessionRule.waitForPageStop()
+
+ // Check that the WebExtension was applied by checking the border color
+ assertBodyBorderEqualTo("red")
+
+ // Uninstall WebExtension and check again
+ sessionRule.waitForResult(controller.uninstall(borderify))
+
+ mainSession.reload()
+ sessionRule.waitForPageStop()
+
+ // Check that the WebExtension was not applied after being uninstalled
+ assertBodyBorderEqualTo("")
+ }
+
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun grantedOptionalPermissions() {
+ sessionRule.setPrefsUntilTestEnd(
+ mapOf(
+ "xpinstall.signatures.required" to false,
+ "extensions.install.requireBuiltInCerts" to false,
+ "extensions.update.requireBuiltInCerts" to false,
+ ),
+ )
+
+ val extension = sessionRule.waitForResult(
+ controller.ensureBuiltIn(
+ "resource://android/assets/web_extensions/optional-permission-request/",
+ "optional-permission-request@example.com",
+ ),
+ )
+
+ assertEquals("optional-permission-request@example.com", extension.id)
+
+ mainSession.loadUri("${extension.metaData.baseUrl}clickToRequestPermission.html")
+ sessionRule.waitForPageStop()
+
+ var grantedOptionalPermissions = extension.metaData.grantedOptionalPermissions
+ var grantedOptionalOrigins = extension.metaData.grantedOptionalOrigins
+
+ assertThat(
+ "grantedOptionalPermissions must be 0.",
+ grantedOptionalPermissions.size,
+ equalTo(0),
+ )
+ assertThat("grantedOptionalOrigins must be 0.", grantedOptionalOrigins.size, equalTo(0))
+
+ // click triggers permissions.request
+ mainSession.synthesizeTap(50, 50)
+
+ sessionRule.delegateUntilTestEnd(object : WebExtensionController.PromptDelegate {
+ override fun onOptionalPrompt(
+ extension: WebExtension,
+ permissions: Array<String>,
+ origins: Array<String>,
+ ): GeckoResult<AllowOrDeny> {
+ return GeckoResult.allow()
+ }
+ })
+
+ var result = GeckoResult<String>()
+ mainSession.webExtensionController.setMessageDelegate(
+ extension,
+ object : WebExtension.MessageDelegate {
+ override fun onMessage(
+ nativeApp: String,
+ message: Any,
+ sender: WebExtension.MessageSender,
+ ): GeckoResult<Any>? {
+ result.complete(message as String)
+ return null
+ }
+ },
+ "browser",
+ )
+
+ result = GeckoResult<String>()
+ val message = sessionRule.waitForResult(result)
+ assertThat("Permission request should be accepted.", message, equalTo("true"))
+
+ val updatedExtension = sessionRule.waitForResult(
+ // Adds "internal:privateBrowsingAllowed"
+ controller.setAllowedInPrivateBrowsing(extension, true),
+ )
+
+ grantedOptionalPermissions = updatedExtension.metaData.grantedOptionalPermissions
+ grantedOptionalOrigins = updatedExtension.metaData.grantedOptionalOrigins
+
+ assertThat(
+ "grantedOptionalPermissions must be 1.",
+ grantedOptionalPermissions.size,
+ equalTo(1),
+ )
+ assertThat("grantedOptionalOrigins must be 1.", grantedOptionalOrigins.size, equalTo(1))
+ assertThat(
+ "grantedOptionalOrigins must be *://example.com/*.",
+ grantedOptionalOrigins.first(),
+ equalTo("*://example.com/*"),
+ )
+
+ // geolocation is part of the manifest but not requested/granted.
+ assertFalse(grantedOptionalPermissions.contains("geolocation"))
+
+ // "internal:privateBrowsingAllowed" must not be part of grantedOptionalPermissions.
+ assertThat(
+ "grantedOptionalPermissions must be activeTab.",
+ grantedOptionalPermissions.first(),
+ equalTo("activeTab"),
+ )
+
+ sessionRule.waitForResult(controller.uninstall(extension))
+ }
+
private fun assertBodyBorderEqualTo(expected: String) {
val color = mainSession.evaluateJS("document.body.style.borderColor")
assertThat(
@@ -1618,6 +1777,11 @@ class WebExtensionTest : BaseSessionTest() {
// - verifies that the messages are received when restoring the tab in a fresh session
@Test
fun testRestoringExtensionPagePreservesMessages() {
+ // TODO: Bug 1884334
+ val geckoPrefs = sessionRule.getPrefs(
+ "fission.disableSessionHistoryInParent",
+ )
+ assumeThat(geckoPrefs[0] as Boolean, Matchers.equalTo(true))
// TODO: Bug 1837551
assumeThat(sessionRule.env.isFission, equalTo(false))
@@ -2138,7 +2302,7 @@ class WebExtensionTest : BaseSessionTest() {
mainSession.waitUntilCalled(object : NavigationDelegate, ProgressDelegate {
@GeckoSessionTestRule.AssertCalled(count = 1)
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat(
"Url should load example.com first",
url,
@@ -2160,7 +2324,7 @@ class WebExtensionTest : BaseSessionTest() {
val pageStop = GeckoResult<Boolean>()
mainSession.delegateUntilTestEnd(object : NavigationDelegate, ProgressDelegate {
- override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
+ override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
page = url
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebNotificationTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebNotificationTest.kt
index 469fd049ce..358134313a 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebNotificationTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebNotificationTest.kt
@@ -31,8 +31,7 @@ class WebNotificationTest : BaseSessionTest() {
// Grant "desktop notification" permission
mainSession.delegateUntilTestEnd(object : PermissionDelegate {
- override fun onContentPermissionRequest(session: GeckoSession, perm: PermissionDelegate.ContentPermission):
- GeckoResult<Int>? {
+ override fun onContentPermissionRequest(session: GeckoSession, perm: PermissionDelegate.ContentPermission): GeckoResult<Int>? {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", perm.permission, equalTo(PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
return GeckoResult.fromValue(PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
@@ -336,7 +335,11 @@ class WebNotificationTest : BaseSessionTest() {
// Test that we can serialize a notification
val parcel = Parcel.obtain()
- notification.writeToParcel(parcel, /* ignored */ -1)
+ notification.writeToParcel(
+ parcel,
+ /* ignored */
+ -1,
+ )
assertThat("Promise should have been resolved.", promiseResult.value as Double, equalTo(1.0))
}
@@ -375,7 +378,11 @@ class WebNotificationTest : BaseSessionTest() {
// Test that we can serialize a notification with an imageUrl.length >= 150
val parcel = Parcel.obtain()
- notification.writeToParcel(parcel, /* ignored */ -1)
+ notification.writeToParcel(
+ parcel,
+ /* ignored */
+ -1,
+ )
parcel.setDataPosition(0)
val serializedNotification = WebNotification.CREATOR.createFromParcel(parcel)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt
index a2e6d58f3a..609275526c 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt
@@ -60,8 +60,7 @@ class WebPushTest : BaseSessionTest() {
sessionRule.setPrefsUntilTestEnd(mapOf("dom.webnotifications.requireuserinteraction" to false))
// Grant "desktop notification" permission
mainSession.delegateUntilTestEnd(object : PermissionDelegate {
- override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
- GeckoResult<Int>? {
+ override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission): GeckoResult<Int>? {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", perm.permission, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
index 9c9a9d6188..727f403931 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -831,7 +831,8 @@ public class GeckoSessionTestRule implements TestRule {
public void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
- @NonNull List<ContentPermission> perms) {}
+ @NonNull List<ContentPermission> perms,
+ @NonNull Boolean hasUserGesture) {}
@Override
public void onShutdown() {}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
index 99be57fc12..3672428a98 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/AndroidGamepadManager.java
@@ -159,9 +159,9 @@ public class AndroidGamepadManager {
/* package */ static void doStart(final Context context) {
ThreadUtils.assertOnUiThread();
if (!sStarted) {
+ sStarted = true;
scanForGamepads();
addDeviceListener(context);
- sStarted = true;
}
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
index 568fc3a0bb..bcd5762a92 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
@@ -46,7 +46,6 @@ import android.os.Looper;
import android.os.PowerManager;
import android.os.Vibrator;
import android.provider.Settings;
-import android.text.TextUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Display;
@@ -1527,20 +1526,6 @@ public class GeckoAppShell {
}
}
- private static String getLanguageTag(final Locale locale) {
- final StringBuilder out = new StringBuilder(locale.getLanguage());
- final String country = locale.getCountry();
- final String variant = locale.getVariant();
- if (!TextUtils.isEmpty(country)) {
- out.append('-').append(country);
- }
- if (!TextUtils.isEmpty(variant)) {
- out.append('-').append(variant);
- }
- // e.g. "en", "en-US", or "en-US-POSIX".
- return out.toString();
- }
-
@WrapForJNI
public static String[] getDefaultLocales() {
// XXX We may have to convert some language codes such as "id" vs "in".
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoDragAndDrop.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoDragAndDrop.java
index 9c1473d4e7..d529449d5a 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoDragAndDrop.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoDragAndDrop.java
@@ -42,7 +42,11 @@ public class GeckoDragAndDrop {
private final Bitmap mBitmap;
public DrawDragImage(final Bitmap bitmap) {
- mBitmap = bitmap;
+ if (bitmap != null && bitmap.getWidth() > 0 && bitmap.getHeight() > 0) {
+ mBitmap = bitmap;
+ return;
+ }
+ mBitmap = null;
}
@Override
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
index 120098a931..56fd0d9853 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/InputMethods.java
@@ -6,11 +6,13 @@
package org.mozilla.gecko;
import android.content.Context;
+import android.os.Build;
import android.provider.Settings.Secure;
import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import java.util.Collection;
+import java.util.Locale;
public final class InputMethods {
public static final String METHOD_ANDROID_LATINIME = "com.android.inputmethod.latin/.LatinIME";
@@ -99,6 +101,13 @@ public final class InputMethods {
return METHOD_SONY.equals(inputMethod);
}
+ // Workaround for bug 1818268 - Unexpected crash on Galaxy J7
+ public static boolean dontOverrideCommitText() {
+ return Build.VERSION.SDK_INT == 23
+ && Build.MANUFACTURER.toLowerCase(Locale.ROOT).equals("samsung")
+ && Build.MODEL.startsWith("SM-J700F");
+ }
+
// TODO: Replace usages by definition in EditorInfoCompat once available (bug 1385726).
public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 0x1000000;
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/MediaDrmProxy.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/MediaDrmProxy.java
index 1bfab37063..4ab8b10f9f 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/MediaDrmProxy.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/MediaDrmProxy.java
@@ -23,6 +23,7 @@ public final class MediaDrmProxy {
private static final String WIDEVINE_KEY_SYSTEM = "com.widevine.alpha";
@WrapForJNI private static final String AAC = "audio/mp4a-latm";
@WrapForJNI private static final String AVC = "video/avc";
+ @WrapForJNI private static final String AV1 = "video/av01";
@WrapForJNI private static final String VORBIS = "audio/vorbis";
@WrapForJNI private static final String VP8 = "video/x-vnd.on2.vp8";
@WrapForJNI private static final String VP9 = "video/x-vnd.on2.vp9";
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/LocaleUtils.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/LocaleUtils.java
new file mode 100644
index 0000000000..8e4addc7b0
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/LocaleUtils.java
@@ -0,0 +1,32 @@
+/* -*- Mode: Java; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*- */
+/* vim: set ts=2 et sw=2: */
+/* 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 org.mozilla.gecko.util;
+
+import android.text.TextUtils;
+import java.util.Locale;
+
+public class LocaleUtils {
+ // Locale.getLanguage() may return legacy language code until Java 17
+ // https://developer.android.com/reference/java/util/Locale#legacy_language_codes
+ public static String getLanguageTagForAcceptLanguage(final Locale locale) {
+ String language = locale.getLanguage();
+ if (language.equals("in")) {
+ language = "id";
+ } else if (language.equals("iw")) {
+ language = "he";
+ } else if (language.equals("ji")) {
+ language = "yi";
+ }
+ final StringBuilder out = new StringBuilder(language);
+ final String country = locale.getCountry();
+ if (!TextUtils.isEmpty(country)) {
+ out.append('-').append(country);
+ }
+ // e.g. "en", "en-US"
+ return out.toString();
+ }
+}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
index aa3f5c3174..bc9eff98f0 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
@@ -37,6 +37,11 @@ import org.mozilla.gecko.annotation.WrapForJNI;
try {
mFd = cr.openAssetFileDescriptor(uri, "r");
+ if (mFd == null) {
+ Log.e(LOGTAG, "Cannot open the uri: " + aUri + " (no file descriptor)");
+ close();
+ return;
+ }
setInputStream(mFd.createInputStream());
if (!checkHeaders(HEADERS)) {
@@ -127,7 +132,17 @@ import org.mozilla.gecko.annotation.WrapForJNI;
|| isExported(context, uri)
|| wasGrantedPermission(context, uri)) {
final ContentResolver cr = context.getContentResolver();
- cr.openAssetFileDescriptor(uri, "r").close();
+ if (cr == null) {
+ Log.e(LOGTAG, "No content resolver");
+ return false;
+ }
+ final AssetFileDescriptor fd = cr.openAssetFileDescriptor(uri, "r");
+ if (fd == null) {
+ // The descriptor can be null because the provider crashed.
+ Log.e(LOGTAG, "No asset file descriptor");
+ return false;
+ }
+ fd.close();
Log.d(LOGTAG, "The uri is readable: " + uri);
return true;
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
index 5426adb501..2e8f2e55d7 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
@@ -655,6 +655,53 @@ import org.mozilla.gecko.util.ThreadUtils;
return replaceComposingSpanWithSelection()
&& mKeyInputConnection.commitText(text, newCursorPosition);
}
+
+ // Bug 1818268 - Unexpected crash on Galaxy J7
+ if (InputMethods.dontOverrideCommitText()) {
+ return super.commitText(text, newCursorPosition);
+ }
+
+ // Default implementation is
+ // 1. Set selection
+ // 2. Call Editable.replace
+ // 3. Set selection in Editable.replace
+ //
+ // However, this results in additional IPC in Gecko and unexpected selection before replacing
+ // text.
+ // When changing text in Gecko, the selection will be updated, so the default implementation is
+ // not compatible with Gecko's text handling.
+ // Therefore, we set the selection after replacing the text. However, if there is a composition,
+ // the selection may be an IME cursor, not a standard selection. In such cases, this step is not
+ // necessary.
+ final Editable content = getEditable();
+ if (content != null) {
+ final int compositionStart = getComposingSpanStart(content);
+ final int compositionEnd = getComposingSpanEnd(content);
+
+ if (compositionStart < 0 || compositionEnd < 0) {
+ // No composition
+ int selStart = Math.max(Selection.getSelectionStart(content), 0);
+ int selEnd = Math.max(Selection.getSelectionEnd(content), 0);
+ if (selStart > selEnd) {
+ final int tmp = selEnd;
+ selEnd = selStart;
+ selStart = tmp;
+ }
+
+ beginBatchEdit();
+ content.replace(selStart, selEnd, text);
+
+ int cursorPosition =
+ newCursorPosition > 0
+ ? selStart + text.length() + newCursorPosition - 1
+ : selStart + newCursorPosition;
+ cursorPosition = Math.min(Math.max(0, cursorPosition), content.length());
+ Selection.setSelection(content, cursorPosition);
+ endBatchEdit();
+ return true;
+ }
+ }
+
return super.commitText(text, newCursorPosition);
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
index 3da044e603..0a80b02b04 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
@@ -27,6 +27,7 @@ import java.util.Locale;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoSystemStateListener;
import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.util.LocaleUtils;
@AnyThread
public final class GeckoRuntimeSettings extends RuntimeSettings {
@@ -462,6 +463,8 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
* @param delegate the delegate that will handle telemetry
* @return The builder instance.
*/
+ @Deprecated
+ @DeprecationSchedule(id = "geckoview-gvst", version = 127)
public @NonNull Builder telemetryDelegate(final @NonNull RuntimeTelemetry.Delegate delegate) {
getSettings().mTelemetryProxy = new RuntimeTelemetry.Proxy(delegate);
getSettings().mTelemetryEnabled.set(true);
@@ -1054,7 +1057,7 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
}
}
// OS prefs come second:
- for (final String locale : getDefaultLocales()) {
+ for (final String locale : getSystemLocalesForAcceptLanguage()) {
final String localeLowerCase = locale.toLowerCase(Locale.ROOT);
if (!locales.containsKey(localeLowerCase)) {
locales.put(localeLowerCase, locale);
@@ -1064,35 +1067,22 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
return TextUtils.join(",", locales.values());
}
- private static String[] getDefaultLocales() {
+ private static String[] getSystemLocalesForAcceptLanguage() {
if (VERSION.SDK_INT >= 24) {
final LocaleList localeList = LocaleList.getDefault();
final String[] locales = new String[localeList.size()];
for (int i = 0; i < localeList.size(); i++) {
- locales[i] = localeList.get(i).toLanguageTag();
+ // accept-language should be language or language-region format.
+ locales[i] = LocaleUtils.getLanguageTagForAcceptLanguage(localeList.get(i));
}
return locales;
}
final String[] locales = new String[1];
final Locale locale = Locale.getDefault();
- locales[0] = locale.toLanguageTag();
+ locales[0] = LocaleUtils.getLanguageTagForAcceptLanguage(locale);
return locales;
}
- private static String getLanguageTag(final Locale locale) {
- final StringBuilder out = new StringBuilder(locale.getLanguage());
- final String country = locale.getCountry();
- final String variant = locale.getVariant();
- if (!TextUtils.isEmpty(country)) {
- out.append('-').append(country);
- }
- if (!TextUtils.isEmpty(variant)) {
- out.append('-').append(variant);
- }
- // e.g. "en", "en-US", or "en-US-POSIX".
- return out.toString();
- }
-
/**
* Sets whether Web Manifest processing support is enabled.
*
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
index f8f7f858e3..85b3abf9a9 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -685,7 +685,11 @@ public class GeckoSession {
final GeckoBundle[] perms = message.getBundleArray("permissions");
final List<PermissionDelegate.ContentPermission> permList =
PermissionDelegate.ContentPermission.fromBundleArray(perms);
- delegate.onLocationChange(GeckoSession.this, message.getString("uri"), permList);
+ delegate.onLocationChange(
+ GeckoSession.this,
+ message.getString("uri"),
+ permList,
+ message.getBoolean("hasUserGesture"));
}
delegate.onCanGoBack(GeckoSession.this, message.getBoolean("canGoBack"));
delegate.onCanGoForward(GeckoSession.this, message.getBoolean("canGoForward"));
@@ -1928,7 +1932,7 @@ public class GeckoSession {
// https://searchfox.org/mozilla-central/source/docshell/base/nsIWebNavigation.idl
//
// We do not use the same values directly in order to insulate ourselves from
- // changes in Gecko. Instead, the flags are converted in GeckoViewNavigation.jsm.
+ // changes in Gecko. Instead, the flags are converted in GeckoViewNavigation.sys.mjs.
/** Default load flag, no special considerations. */
public static final int LOAD_FLAGS_NONE = 0;
@@ -4935,17 +4939,39 @@ public class GeckoSession {
/**
* A view has started loading content from the network.
*
+ * @deprecated use {@link #onLocationChange(GeckoSession, String,
+ * List<PermissionDelegate.ContentPermission>, Boolean) onLocationChange} instead
* @param session The GeckoSession that initiated the callback.
* @param url The resource being loaded.
* @param perms The permissions currently associated with this url.
*/
@UiThread
+ @Deprecated
+ @DeprecationSchedule(id = "geckoview-onlocationchange", version = 127)
default void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
final @NonNull List<PermissionDelegate.ContentPermission> perms) {}
/**
+ * A view has started loading content from the network.
+ *
+ * @param session The GeckoSession that initiated the callback.
+ * @param url The resource being loaded.
+ * @param perms The permissions currently associated with this url.
+ * @param hasUserGesture Whether or not there was an active user gesture when the location
+ * change was requested.
+ */
+ @UiThread
+ default void onLocationChange(
+ @NonNull GeckoSession session,
+ @Nullable String url,
+ final @NonNull List<PermissionDelegate.ContentPermission> perms,
+ final @NonNull Boolean hasUserGesture) {
+ session.getNavigationDelegate().onLocationChange(session, url, perms);
+ }
+
+ /**
* The view's ability to go back has changed.
*
* @param session The GeckoSession that initiated the callback.
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
index 046f7a3072..14f6b14c47 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
@@ -203,7 +203,7 @@ public final class GeckoSessionSettings implements Parcelable {
})
public @interface DisplayMode {}
- // This needs to match GeckoViewSettings.jsm
+ // This needs to match GeckoViewSettings.sys.mjs
/** "browser" value of the display member in Web App Manifests */
public static final int DISPLAY_MODE_BROWSER = 0;
@@ -225,7 +225,7 @@ public final class GeckoSessionSettings implements Parcelable {
})
public @interface UserAgentMode {}
- // This needs to match GeckoViewSettingsChild.js and GeckoViewSettings.jsm
+ // This needs to match GeckoViewSettingsChild.js and GeckoViewSettings.sys.mjs
/** The user agent mode is mobile device */
public static final int USER_AGENT_MODE_MOBILE = 0;
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
index 74eccaeb15..2271ff71f7 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -767,6 +767,9 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
if (super.onKeyUp(keyCode, event)) {
return true;
}
+ if (AndroidGamepadManager.handleKeyEvent(event)) {
+ return true;
+ }
return mSession != null && mSession.getTextInput().onKeyUp(keyCode, event);
}
@@ -775,6 +778,9 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
if (super.onKeyDown(keyCode, event)) {
return true;
}
+ if (AndroidGamepadManager.handleKeyEvent(event)) {
+ return true;
+ }
return mSession != null && mSession.getTextInput().onKeyDown(keyCode, event);
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
index d553a1aa3f..1caa5508ed 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
@@ -1688,7 +1688,7 @@ public class WebExtension {
* in Firefox. </a>
*/
public static class SignedStateFlags {
- // Keep in sync with AddonManager.jsm
+ // Keep in sync with AddonManager.sys.mjs
/**
* This extension may be signed but by a certificate that doesn't chain to our our trusted
* certificate.
@@ -1820,6 +1820,50 @@ public class WebExtension {
public final @NonNull String[] permissions;
/**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">optional
+ * permissions</a> requested or granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] optionalPermissions;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">optional
+ * permissions</a> granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] grantedOptionalPermissions;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">
+ * optional origin permissions</a> requested or granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] optionalOrigins;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">
+ * optional origin permissions</a> granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] grantedOptionalOrigins;
+
+ /**
* Host permissions requested or granted to this extension.
*
* <p>See <a
@@ -1999,6 +2043,10 @@ public class WebExtension {
protected MetaData() {
icon = null;
permissions = null;
+ optionalPermissions = null;
+ grantedOptionalPermissions = null;
+ grantedOptionalOrigins = null;
+ optionalOrigins = null;
origins = null;
name = null;
description = null;
@@ -2029,6 +2077,10 @@ public class WebExtension {
/* package */ MetaData(final GeckoBundle bundle) {
// We only expose permissions that the embedder should prompt for
permissions = bundle.getStringArray("promptPermissions");
+ optionalPermissions = bundle.getStringArray("optionalPermissions");
+ grantedOptionalPermissions = bundle.getStringArray("grantedOptionalPermissions");
+ optionalOrigins = bundle.getStringArray("optionalOrigins");
+ grantedOptionalOrigins = bundle.getStringArray("grantedOptionalOrigins");
origins = bundle.getStringArray("origins");
description = bundle.getString("description");
version = bundle.getString("version");
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
index 10a6eb16cd..5776cf5afc 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -13,6 +13,27 @@ exclude: true
⚠️ breaking change and deprecation notices
+## v125
+- ⚠️ Deprecated [`GeckoSession.NavigationDelegate.onLocationChange`][125.1], to be removed in v127.
+([bug 1837601]({{bugzilla}}1837601))
+- Added [`GeckoSession.NavigationDelegate.onLocationChange#hasUserGesture`][125.2]. This indicates if a location change was requested
+while a user gesture was active (e.g., a tap).
+([bug 1837601]({{bugzilla}}1837601))
+- Added [`WebExtension.MetaData.optionalPermissions`][125.3] and [`WebExtension.MetaData.optionalOrigins`][125.4] which expose the optional and origin optional permissions of an extension ([bug 1811900]({{bugzilla}}1811900)).
+- ⚠️ Deprecated [`RuntimeTelemetry`][125.5], [`GeckoRuntimeSettings.getTelemetryDelegate`][125.6] and [`GeckoRuntimeSettings.telemetryDelegate`][125.7], to be removed in v127.
+([bug 1877836]({{bugzilla}}1877836))
+- Added [`WebExtension.MetaData.grantedOptionalPermissions`][125.8] and [`WebExtension.MetaData.grantedOptionalOrigins`][125.9] which expose the granted optional and origin optional permissions of an extension ([bug 1879543]({{bugzilla}}1879543)).
+
+[125.1]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List)
+[125.2]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List,boolean)
+[125.3]: {{javadoc_uri}}/WebExtension.MetaData.html#optionalPermissions
+[125.4]: {{javadoc_uri}}/WebExtension.MetaData.html#optionalOrigins
+[125.5]: {{javadoc_uri}}/RuntimeTelemetry.html
+[125.6]: {{javadoc_uri}}/GeckoRuntimeSettings.html#getTelemetryDelegate
+[125.7]: {{javadoc_uri}}/GeckoRuntimeSettings.html#telemetryDelegate
+[125.8]: {{javadoc_uri}}/WebExtension.MetaData.html#grantedOptionalPermissions
+[125.9]: {{javadoc_uri}}/WebExtension.MetaData.html#grantedOptionalOrigins
+
## v124
- Added [`GeckoRuntimeSettings#setTrustedRecursiveResolverMode`][124.1] to enable DNS-over-HTTPS using different resolver modes ([bug 1591533]({{bugzilla}}1591533)).
@@ -36,7 +57,7 @@ exclude: true
[123.1]: {{javadoc_uri}}/TranslationsController.RuntimeTranslation.html#checkPairDownloadSize(java.lang.String,java.lang.String)
[123.2]: {{javadoc_uri}}/TranslationsController.TranslationsException.html#ERROR_MODEL_LANGUAGE_REQUIRED
-[121.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
+[123.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
## v122
- ⚠️ Removed [`onGetNimbusFeature`][115.5], please use `ExperimentDelegate.onGetExperimentFeature` instead.
@@ -1519,4 +1540,4 @@ to allow adding gecko profiler markers.
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
[65.25]: {{javadoc_uri}}/GeckoResult.html
-[api-version]: ff5a513251f19534bbf4ebe0084909665d00a227
+[api-version]: fc9fd590333bebf38058b7abddbb7a860cd6e4de
diff --git a/mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/LocaleUtilsTest.java b/mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/LocaleUtilsTest.java
new file mode 100644
index 0000000000..bc6dcc0ced
--- /dev/null
+++ b/mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/LocaleUtilsTest.java
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.util;
+
+import static org.junit.Assert.*;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import java.util.Locale;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+@SmallTest
+public class LocaleUtilsTest {
+ @Test
+ public void languageTagForAcceptLanguage() {
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("zn-Hans-CN")), "zn-CN");
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("zn-Hant-TW")), "zn-TW");
+
+ // If builder is Java 17+, Locale.getLanguage doesn't repelace with old language code.
+ // But we should keep this to make things understandable.
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("id-ID")), "id-ID");
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("in-ID")), "id-ID");
+
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("yi-US")), "yi-US");
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("ji-US")), "yi-US");
+
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("he-IL")), "he-IL");
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(Locale.forLanguageTag("iw-IL")), "he-IL");
+
+ // Android 14 may add extension (Bug 1873578)
+ assertEquals(
+ LocaleUtils.getLanguageTagForAcceptLanguage(
+ Locale.forLanguageTag("en-US-u-fw-mon-mu-celsius")),
+ "en-US");
+ }
+}
diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
index 168a238694..30ae778b8b 100644
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -2624,7 +2624,10 @@ public class GeckoViewActivity extends AppCompatActivity
private class ExampleNavigationDelegate implements GeckoSession.NavigationDelegate {
@Override
public void onLocationChange(
- GeckoSession session, final String url, final List<ContentPermission> perms) {
+ GeckoSession session,
+ final String url,
+ final List<ContentPermission> perms,
+ Boolean hasUserGesture) {
mToolbarView.getLocationView().setText(url);
TabSession tabSession = mTabSessionManager.getSession(session);
if (tabSession != null) {
diff --git a/mobile/android/gradle/with_gecko_binaries.gradle b/mobile/android/gradle/with_gecko_binaries.gradle
index 009a1f586e..0f47e89414 100644
--- a/mobile/android/gradle/with_gecko_binaries.gradle
+++ b/mobile/android/gradle/with_gecko_binaries.gradle
@@ -46,7 +46,7 @@ ext.configureLibraryVariantWithJNIWrappers = { variant, module ->
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}")
} else {
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
- classpath annotationProcessorsJarTask.archivePath
+ classpath annotationProcessorsJarTask.archiveFile
// Configure the classpath at evaluation-time, not at
// configuration-time: see above comment.
@@ -61,7 +61,7 @@ ext.configureLibraryVariantWithJNIWrappers = { variant, module ->
workingDir "${topobjdir}/widget/android"
inputs.file(bundleJar)
- inputs.file(annotationProcessorsJarTask.archivePath)
+ inputs.file(annotationProcessorsJarTask.archiveFile)
inputs.property("module", module)
outputs.file("${topobjdir}/widget/android/GeneratedJNINatives.h")
diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in
index 08361b8870..1e76051ab6 100644
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -43,10 +43,8 @@
#endif
@BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@gkcodecs@DLL_SUFFIX@
-#ifdef MOZ_FFVPX
@BINPATH@/@DLL_PREFIX@mozavutil@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@mozavcodec@DLL_SUFFIX@
-#endif
#ifdef MOZ_OMX_PLUGIN
@BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginkk@DLL_SUFFIX@
diff --git a/mobile/android/modules/geckoview/ChildCrashHandler.sys.mjs b/mobile/android/modules/geckoview/ChildCrashHandler.sys.mjs
index 52a929511a..5c6418091a 100644
--- a/mobile/android/modules/geckoview/ChildCrashHandler.sys.mjs
+++ b/mobile/android/modules/geckoview/ChildCrashHandler.sys.mjs
@@ -30,7 +30,7 @@ export var ChildCrashHandler = {
// Map a child ID to a remote type.
childMap: new Map(),
- // The event listener for this is hooked up in GeckoViewStartup.jsm
+ // The event listener for this is hooked up in GeckoViewStartup.sys.mjs
observe(aSubject, aTopic, aData) {
const childID = aData;
diff --git a/mobile/android/modules/geckoview/GeckoViewContent.sys.mjs b/mobile/android/modules/geckoview/GeckoViewContent.sys.mjs
index b593a6f8e4..240aea0cbe 100644
--- a/mobile/android/modules/geckoview/GeckoViewContent.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewContent.sys.mjs
@@ -345,7 +345,7 @@ export class GeckoViewContent extends GeckoViewModule {
}
// nsIObserver event handler
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe: ${aTopic}`;
this._contentCrashed = false;
const browser = aSubject.ownerElement;
diff --git a/mobile/android/modules/geckoview/GeckoViewMediaControl.sys.mjs b/mobile/android/modules/geckoview/GeckoViewMediaControl.sys.mjs
index 1b39125fce..ebe529e313 100644
--- a/mobile/android/modules/geckoview/GeckoViewMediaControl.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewMediaControl.sys.mjs
@@ -67,7 +67,7 @@ export class GeckoViewMediaControl extends GeckoViewModule {
return this.browser.browsingContext.mediaController;
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent: event=${aEvent}, data=${aData}`;
switch (aEvent) {
diff --git a/mobile/android/modules/geckoview/GeckoViewModule.sys.mjs b/mobile/android/modules/geckoview/GeckoViewModule.sys.mjs
index 87ad35d817..b05244612a 100644
--- a/mobile/android/modules/geckoview/GeckoViewModule.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewModule.sys.mjs
@@ -132,7 +132,7 @@ class EventProxy {
}
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
if (this._enableQueuing) {
debug`queue ${aEvent}, data=${aData}`;
this._eventQueue.unshift(arguments);
@@ -146,7 +146,7 @@ class EventProxy {
this._enableQueuing = aEnable;
}
- _dispatch(aEvent, aData, aCallback) {
+ _dispatch(aEvent, aData) {
debug`dispatch ${aEvent}, data=${aData}`;
if (this.listener.onEvent) {
this.listener.onEvent(...arguments);
diff --git a/mobile/android/modules/geckoview/GeckoViewNavigation.sys.mjs b/mobile/android/modules/geckoview/GeckoViewNavigation.sys.mjs
index 287a605dff..bc098f0413 100644
--- a/mobile/android/modules/geckoview/GeckoViewNavigation.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewNavigation.sys.mjs
@@ -155,7 +155,7 @@ export class GeckoViewNavigation extends GeckoViewModule {
}
// Bundle event handler.
- async onEvent(aEvent, aData, aCallback) {
+ async onEvent(aEvent, aData) {
debug`onEvent: event=${aEvent}, data=${aData}`;
switch (aEvent) {
@@ -291,7 +291,7 @@ export class GeckoViewNavigation extends GeckoViewModule {
return new Promise(resolve => {
const handler = {
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (
aTopic === "geckoview-window-created" &&
aSubject.name === aSessionId
@@ -371,7 +371,7 @@ export class GeckoViewNavigation extends GeckoViewModule {
// Wait indefinitely for app to respond with a browser or null
Services.tm.spinEventLoopUntil(
- "GeckoViewNavigation.jsm:handleNewSession",
+ "GeckoViewNavigation.sys.mjs:handleNewSession",
() => this.window.closed || browser !== undefined
);
return browser || null;
@@ -383,8 +383,7 @@ export class GeckoViewNavigation extends GeckoViewModule {
aOpenWindowInfo,
aWhere,
aFlags,
- aTriggeringPrincipal,
- aCsp
+ aTriggeringPrincipal
) {
debug`createContentWindow: uri=${aUri && aUri.spec}
where=${aWhere} flags=${aFlags}`;
@@ -585,7 +584,7 @@ export class GeckoViewNavigation extends GeckoViewModule {
}
// WebProgress event handler.
- onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
+ onLocationChange(aWebProgress, aRequest, aLocationURI) {
debug`onLocationChange`;
let fixedURI = aLocationURI;
@@ -648,6 +647,8 @@ export class GeckoViewNavigation extends GeckoViewModule {
canGoForward: this.browser.canGoForward,
isTopLevel: aWebProgress.isTopLevel,
permissions,
+ hasUserGesture:
+ this.window.document.hasValidTransientUserGestureActivation,
};
lazy.TranslationsParent.onLocationChange(this.browser);
this.eventDispatcher.sendRequest(message);
diff --git a/mobile/android/modules/geckoview/GeckoViewProcessHangMonitor.sys.mjs b/mobile/android/modules/geckoview/GeckoViewProcessHangMonitor.sys.mjs
index 7f6f14a29e..387fda4421 100644
--- a/mobile/android/modules/geckoview/GeckoViewProcessHangMonitor.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewProcessHangMonitor.sys.mjs
@@ -65,7 +65,7 @@ export class GeckoViewProcessHangMonitor extends GeckoViewModule {
}
// Bundle event handler.
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent: event=${aEvent}, data=${aData}`;
if (this._reportIndex.has(aData.hangId)) {
@@ -84,7 +84,7 @@ export class GeckoViewProcessHangMonitor extends GeckoViewModule {
}
// nsIObserver event handler
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe(aTopic=${aTopic})`;
aSubject.QueryInterface(Ci.nsIHangReport);
if (!aSubject.isReportForBrowserOrChildren(this.browser.frameLoader)) {
diff --git a/mobile/android/modules/geckoview/GeckoViewProgress.sys.mjs b/mobile/android/modules/geckoview/GeckoViewProgress.sys.mjs
index 66aceb974c..3cad6e977a 100644
--- a/mobile/android/modules/geckoview/GeckoViewProgress.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewProgress.sys.mjs
@@ -557,7 +557,7 @@ export class GeckoViewProgress extends GeckoViewModule {
}
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent: event=${aEvent}, data=${aData}`;
switch (aEvent) {
@@ -608,6 +608,7 @@ export class GeckoViewProgress extends GeckoViewModule {
canGoBack: false,
canGoForward: false,
isTopLevel: true,
+ hasUserGesture: false,
});
this.eventDispatcher.sendRequest({
type: "GeckoView:PageStop",
@@ -616,7 +617,7 @@ export class GeckoViewProgress extends GeckoViewModule {
}
// nsIObserver event handler
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe: topic=${aTopic}`;
switch (aTopic) {
diff --git a/mobile/android/modules/geckoview/GeckoViewPushController.sys.mjs b/mobile/android/modules/geckoview/GeckoViewPushController.sys.mjs
index da2d7d04e9..07ad8cd514 100644
--- a/mobile/android/modules/geckoview/GeckoViewPushController.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewPushController.sys.mjs
@@ -27,7 +27,7 @@ function createScopeAndPrincipal(scopeAndAttrs) {
}
export const GeckoViewPushController = {
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent ${aEvent} ${aData}`;
switch (aEvent) {
diff --git a/mobile/android/modules/geckoview/GeckoViewSelectionAction.sys.mjs b/mobile/android/modules/geckoview/GeckoViewSelectionAction.sys.mjs
index 07498e4b00..cc3b153716 100644
--- a/mobile/android/modules/geckoview/GeckoViewSelectionAction.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewSelectionAction.sys.mjs
@@ -20,7 +20,7 @@ export class GeckoViewSelectionAction extends GeckoViewModule {
}
// Bundle event handler.
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent: ${aEvent}`;
switch (aEvent) {
diff --git a/mobile/android/modules/geckoview/GeckoViewSessionStore.sys.mjs b/mobile/android/modules/geckoview/GeckoViewSessionStore.sys.mjs
index 584429295e..faa5c5f280 100644
--- a/mobile/android/modules/geckoview/GeckoViewSessionStore.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewSessionStore.sys.mjs
@@ -112,7 +112,7 @@ export var GeckoViewSessionStore = {
// For each <browser> element, records the SHistoryListener.
_browserSHistoryListener: new WeakMap(),
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe ${aTopic}`;
switch (aTopic) {
diff --git a/mobile/android/modules/geckoview/GeckoViewStorageController.sys.mjs b/mobile/android/modules/geckoview/GeckoViewStorageController.sys.mjs
index e69ad3b973..0f4e692ba9 100644
--- a/mobile/android/modules/geckoview/GeckoViewStorageController.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewStorageController.sys.mjs
@@ -308,7 +308,7 @@ export const GeckoViewStorageController = {
new Promise(resolve => {
Services.clearData.deleteData(flags, resolve);
- }).then(resultFlags => {
+ }).then(() => {
aCallback.onSuccess();
});
},
@@ -321,7 +321,7 @@ export const GeckoViewStorageController = {
convertFlags(aFlags),
resolve
);
- }).then(resultFlags => {
+ }).then(() => {
aCallback.onSuccess();
});
},
@@ -334,7 +334,7 @@ export const GeckoViewStorageController = {
convertFlags(aFlags),
resolve
);
- }).then(resultFlags => {
+ }).then(() => {
aCallback.onSuccess();
});
},
diff --git a/mobile/android/modules/geckoview/GeckoViewTab.sys.mjs b/mobile/android/modules/geckoview/GeckoViewTab.sys.mjs
index 53f43f153c..fe984934ec 100644
--- a/mobile/android/modules/geckoview/GeckoViewTab.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewTab.sys.mjs
@@ -116,7 +116,7 @@ export const GeckoViewTabBridge = {
// need to start waiting before we send the message.
const windowPromise = new Promise(resolve => {
const handler = {
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (
aTopic === "geckoview-window-created" &&
aSubject.name === newSessionId
@@ -203,7 +203,7 @@ export class GeckoViewTab extends GeckoViewModule {
this.registerListener(["GeckoView:WebExtension:SetTabActive"]);
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent: event=${aEvent}, data=${aData}`;
switch (aEvent) {
diff --git a/mobile/android/modules/geckoview/GeckoViewTelemetry.sys.mjs b/mobile/android/modules/geckoview/GeckoViewTelemetry.sys.mjs
index bb7074ced8..c5738e672c 100644
--- a/mobile/android/modules/geckoview/GeckoViewTelemetry.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewTelemetry.sys.mjs
@@ -33,12 +33,16 @@ export class GleanStopwatch {
}
finish() {
- this._metric.stopAndAccumulate(this._timerId);
- this._timerId = null;
+ if (this.isRunning()) {
+ this._metric.stopAndAccumulate(this._timerId);
+ this._timerId = null;
+ }
}
cancel() {
- this._metric.cancel(this._timerId);
- this._timerId = null;
+ if (this.isRunning()) {
+ this._metric.cancel(this._timerId);
+ this._timerId = null;
+ }
}
}
diff --git a/mobile/android/modules/geckoview/GeckoViewTestUtils.sys.mjs b/mobile/android/modules/geckoview/GeckoViewTestUtils.sys.mjs
index 6c5113cdc2..a2ca252cdd 100644
--- a/mobile/android/modules/geckoview/GeckoViewTestUtils.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewTestUtils.sys.mjs
@@ -20,7 +20,7 @@ export const GeckoViewTabUtil = {
async createNewTab(url = "about:blank") {
let sessionId = "";
const windowPromise = new Promise(resolve => {
- const openingObserver = (subject, topic, data) => {
+ const openingObserver = subject => {
if (subject.name === sessionId) {
Services.obs.removeObserver(
openingObserver,
diff --git a/mobile/android/modules/geckoview/GeckoViewTranslations.sys.mjs b/mobile/android/modules/geckoview/GeckoViewTranslations.sys.mjs
index 3db694a64a..7e74e7bf30 100644
--- a/mobile/android/modules/geckoview/GeckoViewTranslations.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewTranslations.sys.mjs
@@ -182,7 +182,7 @@ export const GeckoViewTranslationsSettings = {
if (operation === "delete") {
if (operationLevel === "all") {
lazy.TranslationsParent.deleteAllLanguageFiles().then(
- function (value) {
+ function () {
aCallback.onSuccess();
},
function (error) {
@@ -201,7 +201,7 @@ export const GeckoViewTranslationsSettings = {
return;
}
lazy.TranslationsParent.deleteLanguageFiles(language).then(
- function (value) {
+ function () {
aCallback.onSuccess();
},
function (error) {
@@ -216,7 +216,7 @@ export const GeckoViewTranslationsSettings = {
if (operation === "download") {
if (operationLevel === "all") {
lazy.TranslationsParent.downloadAllFiles().then(
- function (value) {
+ function () {
aCallback.onSuccess();
},
function (error) {
@@ -235,7 +235,7 @@ export const GeckoViewTranslationsSettings = {
return;
}
lazy.TranslationsParent.downloadLanguageFiles(language).then(
- function (value) {
+ function () {
aCallback.onSuccess();
},
function (error) {
diff --git a/mobile/android/modules/geckoview/GeckoViewUtils.sys.mjs b/mobile/android/modules/geckoview/GeckoViewUtils.sys.mjs
index ddfb40c1a1..3fe8309b6b 100644
--- a/mobile/android/modules/geckoview/GeckoViewUtils.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewUtils.sys.mjs
@@ -25,7 +25,7 @@ class AndroidFormatter extends Log.BasicFormatter {
/*
* AndroidAppender
- * Logs to Android logcat using AndroidLog.jsm
+ * Logs to Android logcat using AndroidLog.sys.mjs
*/
class AndroidAppender extends Log.Appender {
constructor(aFormatter) {
@@ -49,7 +49,7 @@ class AndroidAppender extends Log.Appender {
return;
}
- // AndroidLog.jsm always prepends "Gecko" to the tag, so we strip any
+ // AndroidLog.sys.mjs always prepends "Gecko" to the tag, so we strip any
// leading "Gecko" here. Also strip dots to save space.
const tag = aMessage.loggerName.replace(/^Gecko|\./g, "");
const msg = this._formatter.format(aMessage);
@@ -257,9 +257,7 @@ export var GeckoViewUtils = {
(handlers, observer, args) => {
if (!once) {
Services.prefs.removeObserver(args[2], observer);
- handlers.forEach(handler =>
- Services.prefs.addObserver(args[2], observer)
- );
+ handlers.forEach(() => Services.prefs.addObserver(args[2], observer));
}
handlers.forEach(handler => handler.observe(...args));
}
@@ -386,7 +384,7 @@ export var GeckoViewUtils = {
* do_something(bar); // No log.
* do_something(debug.foo = bar); // Output "foo = 42" to the log.
*
- * @param aTag Name of the Log.jsm logger to forward logs to.
+ * @param aTag Name of the Log.sys.mjs logger to forward logs to.
* @param aScope Scope to add the logging functions to.
*/
initLogging(aTag, aScope) {
diff --git a/mobile/android/modules/geckoview/GeckoViewWebExtension.sys.mjs b/mobile/android/modules/geckoview/GeckoViewWebExtension.sys.mjs
index ae821a3656..97538fd6bb 100644
--- a/mobile/android/modules/geckoview/GeckoViewWebExtension.sys.mjs
+++ b/mobile/android/modules/geckoview/GeckoViewWebExtension.sys.mjs
@@ -158,7 +158,7 @@ class EmbedderPort {
data: holder.deserialize({}),
});
}
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
debug`onEvent ${aEvent} ${aData}`;
switch (aEvent) {
@@ -360,6 +360,23 @@ async function exportExtension(aAddon, aPermissions, aSourceURI) {
updateDate = null;
}
+ const normalizePermissions = perms => {
+ if (perms?.permissions) {
+ perms = { ...perms };
+ perms.permissions = perms.permissions.filter(
+ perm => !perm.startsWith("internal:")
+ );
+ }
+ return perms;
+ };
+
+ const optionalPermissions = aAddon.optionalPermissions?.permissions ?? [];
+ const optionalOrigins = aAddon.optionalPermissions?.origins ?? [];
+ const grantedPermissions =
+ normalizePermissions(await lazy.ExtensionPermissions.get(id)) ?? [];
+ const grantedOptionalPermissions = grantedPermissions?.permissions ?? [];
+ const grantedOptionalOrigins = grantedPermissions?.origins ?? [];
+
return {
webExtensionId: id,
locationURI: aSourceURI != null ? aSourceURI.spec : "",
@@ -393,6 +410,10 @@ async function exportExtension(aAddon, aPermissions, aSourceURI) {
temporary: temporarilyInstalled,
updateDate,
version,
+ optionalPermissions,
+ optionalOrigins,
+ grantedOptionalPermissions,
+ grantedOptionalOrigins,
},
};
}
@@ -528,7 +549,7 @@ class ExtensionPromptObserver {
resolve(response.allow);
}
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe ${aTopic}`;
switch (aTopic) {
@@ -572,7 +593,7 @@ class AddonInstallObserver {
});
}
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe ${aTopic}`;
switch (aTopic) {
case "addon-install-failed": {
@@ -758,7 +779,7 @@ class ExtensionProcessListener {
]);
}
- async onEvent(aEvent, aData, aCallback) {
+ async onEvent(aEvent, aData) {
debug`onEvent ${aEvent} ${aData}`;
switch (aEvent) {
@@ -872,7 +893,7 @@ async function updatePromptHandler(aInfo) {
}
export var GeckoViewWebExtension = {
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
debug`observe ${aTopic}`;
switch (aTopic) {
diff --git a/mobile/android/modules/geckoview/LoadURIDelegate.sys.mjs b/mobile/android/modules/geckoview/LoadURIDelegate.sys.mjs
index 5769fcafe8..fa65b8a2e2 100644
--- a/mobile/android/modules/geckoview/LoadURIDelegate.sys.mjs
+++ b/mobile/android/modules/geckoview/LoadURIDelegate.sys.mjs
@@ -40,7 +40,7 @@ export const LoadURIDelegate = {
}
);
Services.tm.spinEventLoopUntil(
- "LoadURIDelegate.jsm:load",
+ "LoadURIDelegate.sys.mjs:load",
() => aWindow.closed || handled !== undefined
);
@@ -75,13 +75,13 @@ export const LoadURIDelegate = {
Components.returnCode = Cr.NS_ERROR_ABORT;
}
},
- e => {
+ () => {
errorPageURI = null;
Components.returnCode = Cr.NS_ERROR_ABORT;
}
);
Services.tm.spinEventLoopUntil(
- "LoadURIDelegate.jsm:handleLoadError",
+ "LoadURIDelegate.sys.mjs:handleLoadError",
() => aWindow.closed || errorPageURI !== undefined
);
diff --git a/mobile/android/modules/geckoview/Messaging.sys.mjs b/mobile/android/modules/geckoview/Messaging.sys.mjs
index e67161fede..fff0b4311c 100644
--- a/mobile/android/modules/geckoview/Messaging.sys.mjs
+++ b/mobile/android/modules/geckoview/Messaging.sys.mjs
@@ -11,10 +11,10 @@ class ChildActorDispatcher {
}
// TODO: Bug 1658980
- registerListener(aListener, aEvents) {
+ registerListener() {
throw new Error("Cannot registerListener in child actor");
}
- unregisterListener(aListener, aEvents) {
+ unregisterListener() {
throw new Error("Cannot registerListener in child actor");
}
diff --git a/mobile/android/modules/geckoview/test/xpcshell/test_ChildCrashHandler.js b/mobile/android/modules/geckoview/test/xpcshell/test_ChildCrashHandler.js
index 0e07937ed3..ee03e2ba4a 100644
--- a/mobile/android/modules/geckoview/test/xpcshell/test_ChildCrashHandler.js
+++ b/mobile/android/modules/geckoview/test/xpcshell/test_ChildCrashHandler.js
@@ -41,7 +41,7 @@ add_task(async function test_remoteType() {
let listener;
const crashReportPromise = new Promise(resolve => {
listener = {
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
resolve([aEvent, aData]);
},
};
@@ -79,7 +79,7 @@ add_task(async function test_extensions_process_crash() {
let listener;
const crashReportPromise = new Promise(resolve => {
listener = {
- onEvent(aEvent, aData, aCallback) {
+ onEvent(aEvent, aData) {
resolve([aEvent, aData]);
},
};
diff --git a/mobile/android/test_runner/src/main/java/org/mozilla/geckoview/test_runner/TestRunnerActivity.java b/mobile/android/test_runner/src/main/java/org/mozilla/geckoview/test_runner/TestRunnerActivity.java
index 3930ab545c..399f9417c2 100644
--- a/mobile/android/test_runner/src/main/java/org/mozilla/geckoview/test_runner/TestRunnerActivity.java
+++ b/mobile/android/test_runner/src/main/java/org/mozilla/geckoview/test_runner/TestRunnerActivity.java
@@ -163,7 +163,10 @@ public class TestRunnerActivity extends Activity {
new GeckoSession.NavigationDelegate() {
@Override
public void onLocationChange(
- final GeckoSession session, final String url, final List<ContentPermission> perms) {
+ final GeckoSession session,
+ final String url,
+ final List<ContentPermission> perms,
+ final Boolean hasUserGesture) {
getActionBar().setSubtitle(url);
}
diff --git a/mobile/ios/app.mozbuild b/mobile/ios/app.mozbuild
new file mode 100644
index 0000000000..af3e729a4a
--- /dev/null
+++ b/mobile/ios/app.mozbuild
@@ -0,0 +1,10 @@
+# vim: set filetype=python:
+# 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/.
+
+include("/toolkit/toolkit.mozbuild")
+
+DIRS += [
+ "/mobile/ios",
+]
diff --git a/mobile/ios/build.mk b/mobile/ios/build.mk
new file mode 100644
index 0000000000..1e0afc0a68
--- /dev/null
+++ b/mobile/ios/build.mk
@@ -0,0 +1,5 @@
+package:
+ $(MAKE) -C mobile/ios/installer
+
+upload:
+ $(MAKE) -C mobile/ios/installer upload
diff --git a/mobile/ios/config/mozconfigs/ios-sim/debug b/mobile/ios/config/mozconfigs/ios-sim/debug
new file mode 100644
index 0000000000..ea0501d224
--- /dev/null
+++ b/mobile/ios/config/mozconfigs/ios-sim/debug
@@ -0,0 +1,3 @@
+. $topsrcdir/mobile/ios/config/mozconfigs/ios-sim/opt
+
+ac_add_options --enable-debug
diff --git a/mobile/ios/config/mozconfigs/ios-sim/opt b/mobile/ios/config/mozconfigs/ios-sim/opt
new file mode 100644
index 0000000000..aeaf6aa0c3
--- /dev/null
+++ b/mobile/ios/config/mozconfigs/ios-sim/opt
@@ -0,0 +1,6 @@
+ac_add_options --enable-project=mobile/ios
+ac_add_options --target=aarch64-apple-ios-sim
+ac_add_options --enable-clang-plugin
+
+. "$topsrcdir/build/mozconfig.cache"
+. "$topsrcdir/build/mozconfig.automation"
diff --git a/mobile/ios/config/mozconfigs/ios/debug b/mobile/ios/config/mozconfigs/ios/debug
new file mode 100644
index 0000000000..279ebb2053
--- /dev/null
+++ b/mobile/ios/config/mozconfigs/ios/debug
@@ -0,0 +1,3 @@
+. $topsrcdir/mobile/ios/config/mozconfigs/ios/opt
+
+ac_add_options --enable-debug
diff --git a/mobile/ios/config/mozconfigs/ios/debug-searchfox b/mobile/ios/config/mozconfigs/ios/debug-searchfox
new file mode 100644
index 0000000000..a027cd8921
--- /dev/null
+++ b/mobile/ios/config/mozconfigs/ios/debug-searchfox
@@ -0,0 +1,8 @@
+MOZ_AUTOMATION_BUILD_SYMBOLS=0
+MOZ_AUTOMATION_CHECK=0
+
+. $topsrcdir/mobile/ios/config/mozconfigs/ios/opt
+
+ac_add_options --enable-debug
+
+ac_add_options --enable-mozsearch-plugin
diff --git a/mobile/ios/config/mozconfigs/ios/opt b/mobile/ios/config/mozconfigs/ios/opt
new file mode 100644
index 0000000000..4cde731827
--- /dev/null
+++ b/mobile/ios/config/mozconfigs/ios/opt
@@ -0,0 +1,5 @@
+ac_add_options --enable-project=mobile/ios
+ac_add_options --enable-clang-plugin
+
+. "$topsrcdir/build/mozconfig.cache"
+. "$topsrcdir/build/mozconfig.automation"
diff --git a/mobile/ios/installer/Makefile.in b/mobile/ios/installer/Makefile.in
new file mode 100644
index 0000000000..1d4c4ff321
--- /dev/null
+++ b/mobile/ios/installer/Makefile.in
@@ -0,0 +1,11 @@
+# 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/.
+
+STANDALONE_MAKEFILE := 1
+
+include $(topsrcdir)/config/rules.mk
+
+MOZ_PKG_DUPEFLAGS = -f $(srcdir)/allowed-dupes.mn
+
+include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
diff --git a/mobile/ios/installer/allowed-dupes.mn b/mobile/ios/installer/allowed-dupes.mn
new file mode 100644
index 0000000000..078bbe4e09
--- /dev/null
+++ b/mobile/ios/installer/allowed-dupes.mn
@@ -0,0 +1,26 @@
+# Known duplicate files
+# This file is ideally removed, but some existing files will be allowed exceptions
+# See bug 1303184
+#
+# PLEASE DO NOT ADD MORE EXCEPTIONS TO THIS LIST
+#
+
+# Row and column icons are duplicated
+res/table-remove-column-active.gif
+res/table-remove-row-active.gif
+res/table-remove-column-hover.gif
+res/table-remove-row-hover.gif
+res/table-remove-column.gif
+res/table-remove-row.gif
+
+res/multilocale.txt
+update.locale
+
+# Bug 1833829 - Rolling out new search configuration.
+defaults/settings/main/search-config-icons/47da97b5-600f-c450-fd15-a52bb2169c11
+defaults/settings/main/search-config-icons/fed4f021-ff3e-942a-010e-afa43fda2136
+defaults/settings/main/search-config-icons/6a83583a-f0ba-fd39-2fdb-fd2b6990ea3b
+defaults/settings/main/search-config-icons/f312610a-ebfb-a106-ea92-fd643c5d3636
+
+components/httpd.sys.mjs
+chrome/remote/content/server/httpd.sys.mjs
diff --git a/mobile/ios/moz.build b/mobile/ios/moz.build
new file mode 100644
index 0000000000..2253746e12
--- /dev/null
+++ b/mobile/ios/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+CONFIGURE_SUBST_FILES += ["installer/Makefile"]
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "General")
diff --git a/mobile/ios/moz.configure b/mobile/ios/moz.configure
new file mode 100644
index 0000000000..b02ed1347e
--- /dev/null
+++ b/mobile/ios/moz.configure
@@ -0,0 +1,16 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+imply_option("MOZ_PLACES", True)
+
+
+@depends(target)
+def check_target(target):
+ if target.os != "iOS":
+ die("Cannot build mobile/ios with a target other than an iOS one")
+
+
+include("../../toolkit/moz.configure")