diff --git a/.eslintignore b/.eslintignore
index 044c26f480a3..d3c457cad62b 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -80,9 +80,8 @@ browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
browser/components/enterprisepolicies/schemas/schema.jsm
# generated & special files in cld2
browser/components/translation/cld2/**
-# Screenshots and Follow-on search are imported as a system add-on and have
+# Screenshots is imported as a system add-on and has
# their own lint rules currently.
-browser/extensions/followonsearch/**
browser/extensions/screenshots/**
browser/extensions/pdfjs/content/build**
browser/extensions/pdfjs/content/web**
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 5e80a101160f..1dadd0585c4e 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1051,7 +1051,7 @@ pref("security.sandbox.content.level", 3);
// 2 - "read access triggered by file dialog activity, limited read/write"
// "access for Flash functionality"
// 3 - "limited read/write access for Flash functionality"
-pref("dom.ipc.plugins.sandbox-level.flash", 2);
+pref("dom.ipc.plugins.sandbox-level.flash", 1);
// Controls the level used on older OS X versions. Is overriden when the
// "dom.ipc.plugins.sandbox-level.flash" is set to 0.
pref("dom.ipc.plugins.sandbox-level.flash.legacy", 1);
@@ -1060,7 +1060,7 @@ pref("dom.ipc.plugins.sandbox-level.flash.max-legacy-os-minor", 10);
// Controls the sandbox level used by plugins other than Flash. On Mac,
// no other plugins are supported and this pref is only used for test
// plugins used in automated tests.
-pref("dom.ipc.plugins.sandbox-level.default", 2);
+pref("dom.ipc.plugins.sandbox-level.default", 1);
#endif
#if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
diff --git a/browser/base/content/test/performance/browser_startup.js b/browser/base/content/test/performance/browser_startup.js
index 9bb6e627a9ac..a7a2156e0498 100644
--- a/browser/base/content/test/performance/browser_startup.js
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -36,6 +36,7 @@ const startupPhases = {
modules: new Set([
"resource://gre/modules/AppConstants.jsm",
"resource://gre/modules/ActorManagerParent.jsm",
+ "resource://gre/modules/CustomElementsListener.jsm",
"resource://gre/modules/ExtensionUtils.jsm",
"resource://gre/modules/XPCOMUtils.jsm",
"resource://gre/modules/Services.jsm",
diff --git a/browser/components/extensions/parent/ext-menus.js b/browser/components/extensions/parent/ext-menus.js
index 555ce33c6654..7a398bbfe467 100644
--- a/browser/components/extensions/parent/ext-menus.js
+++ b/browser/components/extensions/parent/ext-menus.js
@@ -580,6 +580,7 @@ MenuItem.prototype = {
checked: false,
contexts: ["all"],
enabled: true,
+ visible: true,
});
},
@@ -708,6 +709,9 @@ MenuItem.prototype = {
},
enabledForContext(contextData) {
+ if (!this.visible) {
+ return false;
+ }
let contexts = getMenuContexts(contextData);
if (!this.contexts.some(n => contexts.has(n))) {
return false;
diff --git a/browser/components/extensions/schemas/menus.json b/browser/components/extensions/schemas/menus.json
index e5176f6f4824..b40b160ac45e 100644
--- a/browser/components/extensions/schemas/menus.json
+++ b/browser/components/extensions/schemas/menus.json
@@ -197,6 +197,11 @@
"optional": true,
"description": "List of contexts this menu item will appear in. Defaults to ['page'] if not specified."
},
+ "visible": {
+ "type": "boolean",
+ "optional": true,
+ "description": "Whether the item is visible in the menu."
+ },
"onclick": {
"type": "function",
"optional": true,
@@ -294,6 +299,11 @@
"minItems": 1,
"optional": true
},
+ "visible": {
+ "type": "boolean",
+ "optional": true,
+ "description": "Whether the item is visible in the menu."
+ },
"onclick": {
"type": "function",
"optional": "omit-key-if-missing",
diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini
index 0b41b56d4ce5..5eea24e3cabf 100644
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -115,6 +115,7 @@ skip-if = (verify && (os == 'linux' || os == 'mac'))
[browser_ext_menus_targetElement.js]
[browser_ext_menus_targetElement_extension.js]
[browser_ext_menus_targetElement_shadow.js]
+[browser_ext_menus_visible.js]
[browser_ext_omnibox.js]
[browser_ext_openPanel.js]
skip-if = (verify && !debug && (os == 'linux' || os == 'mac'))
diff --git a/browser/components/extensions/test/browser/browser_ext_menus_visible.js b/browser/components/extensions/test/browser/browser_ext_menus_visible.js
new file mode 100644
index 000000000000..941830d8e1c9
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_menus_visible.js
@@ -0,0 +1,86 @@
+/* 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/. */
+"use strict";
+
+const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html";
+
+add_task(async function visible_false() {
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
+
+ async function background() {
+ browser.menus.onShown.addListener(info => {
+ browser.test.assertEq("[]", JSON.stringify(info.menuIds), "Expected no menu items");
+ browser.test.sendMessage("done");
+ });
+ browser.menus.create({
+ id: "create-visible-false",
+ title: "invisible menu item",
+ visible: false,
+ });
+ browser.menus.create({
+ id: "update-without-params",
+ title: "invisible menu item",
+ visible: false,
+ });
+ await browser.menus.update("update-without-params", {});
+ browser.menus.create({
+ id: "update-visible-to-false",
+ title: "initially visible menu item",
+ });
+ await browser.menus.update("update-visible-to-false", {visible: false});
+ browser.test.sendMessage("ready");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["menus"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+ await openContextMenu();
+ await extension.awaitMessage("done");
+ await closeContextMenu();
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function visible_true() {
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
+
+ async function background() {
+ browser.menus.onShown.addListener(info => {
+ browser.test.assertEq(`["update-to-true"]`, JSON.stringify(info.menuIds), "Expected no menu items");
+ browser.test.sendMessage("done");
+ });
+ browser.menus.create({
+ id: "update-to-true",
+ title: "invisible menu item",
+ visible: false,
+ });
+ await browser.menus.update("update-to-true", {visible: true});
+ browser.test.sendMessage("ready");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["menus"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+ await openContextMenu();
+ await extension.awaitMessage("done");
+ await closeContextMenu();
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});
diff --git a/browser/components/search/test/browser_searchEngine_behaviors.js b/browser/components/search/test/browser_searchEngine_behaviors.js
index 51d07093c26f..9ac960186571 100644
--- a/browser/components/search/test/browser_searchEngine_behaviors.js
+++ b/browser/components/search/test/browser_searchEngine_behaviors.js
@@ -103,6 +103,7 @@ async function testSearchEngine(engineDetails) {
// Test search URLs (including purposes).
let url = engine.getSubmission("foo").uri.spec;
Assert.equal(url, base + engineDetails.codes.submission, "Check search URL for 'foo'");
+ let sb = BrowserSearch.searchBar;
let engineTests = [
{
@@ -136,12 +137,8 @@ async function testSearchEngine(engineDetails) {
name: "search bar search",
searchURL: base + engineDetails.codes.submission,
run() {
- let sb = BrowserSearch.searchBar;
sb.focus();
sb.value = "foo";
- registerCleanupFunction(function() {
- sb.value = "";
- });
EventUtils.synthesizeKey("KEY_Enter");
}
},
@@ -185,5 +182,6 @@ async function testSearchEngine(engineDetails) {
}
engine.alias = undefined;
+ sb.value = "";
BrowserTestUtils.removeTab(tab);
}
diff --git a/browser/extensions/followonsearch/.eslintrc.js b/browser/extensions/followonsearch/.eslintrc.js
deleted file mode 100644
index 7086cdb848d6..000000000000
--- a/browser/extensions/followonsearch/.eslintrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-"use strict";
-
-module.exports = {
- "env": {
- "browser": true,
- "node": false
- }
-};
diff --git a/browser/extensions/followonsearch/bootstrap.js b/browser/extensions/followonsearch/bootstrap.js
deleted file mode 100644
index 276d72e33f5e..000000000000
--- a/browser/extensions/followonsearch/bootstrap.js
+++ /dev/null
@@ -1,192 +0,0 @@
-/* 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/. */
-
-/* global APP_SHUTDOWN:false */
-
-"use strict";
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/Timer.jsm");
-
-// Preferences this add-on uses.
-const kPrefPrefix = "extensions.followonsearch.";
-const PREF_LOGGING = `${kPrefPrefix}logging`;
-
-const kExtensionID = "followonsearch@mozilla.com";
-const kSaveTelemetryMsg = `${kExtensionID}:save-telemetry`;
-const kShutdownMsg = `${kExtensionID}:shutdown`;
-
-const frameScript = `chrome://followonsearch/content/followonsearch-fs.js?q=${Math.random()}`;
-
-const validSearchTypes = [
- // A search is a follow-on search from an SAP.
- "follow-on",
- // The search is a "search access point".
- "sap",
-];
-
-var gLoggingEnabled = false;
-var gTelemetryActivated = false;
-
-/**
- * Logs a message to the console if logging is enabled.
- *
- * @param {String} message The message to log.
- */
-function log(message) {
- if (gLoggingEnabled) {
- console.log("Follow-On Search", message);
- }
-}
-
-/**
- * Handles receiving a message from the content process to save telemetry.
- *
- * @param {Object} message The message received.
- */
-function handleSaveTelemetryMsg(message) {
- if (message.name != kSaveTelemetryMsg) {
- throw new Error(`Unexpected message received: ${message.name}`);
- }
-
- let info = message.data;
-
- if (!validSearchTypes.includes(info.type)) {
- throw new Error("Unexpected type!");
- }
-
- log(info);
-
- let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- let payload = `${info.sap}.${info.type}:unknown:${info.code}`;
- if (info.extra) {
- payload += `:${info.extra}`
- }
- histogram.add(payload);
-}
-
-/**
- * Activates recording of telemetry if it isn't already activated.
- */
-function activateTelemetry() {
- if (gTelemetryActivated) {
- return;
- }
-
- gTelemetryActivated = true;
-
- Services.mm.addMessageListener(kSaveTelemetryMsg, handleSaveTelemetryMsg);
- Services.mm.loadFrameScript(frameScript, true);
-}
-
-/**
- * Deactivites recording of telemetry if it isn't already deactivated.
- */
-function deactivateTelemetry() {
- if (!gTelemetryActivated) {
- return;
- }
-
- Services.mm.removeMessageListener(kSaveTelemetryMsg, handleSaveTelemetryMsg);
- Services.mm.removeDelayedFrameScript(frameScript);
- Services.mm.broadcastAsyncMessage(kShutdownMsg);
-
- gTelemetryActivated = false;
-}
-
-/**
- * cohortManager is used to decide which users to enable the add-on for.
- */
-var cohortManager = {
- // Indicates whether the telemetry should be enabled.
- enableForUser: false,
-
- // Records if we've already run init.
- _definedThisSession: false,
-
- /**
- * Initialises the manager, working out if telemetry should be enabled
- * for the user.
- */
- init() {
- if (this._definedThisSession) {
- return;
- }
-
- this._definedThisSession = true;
- this.enableForUser = false;
-
- try {
- let distId = Services.prefs.getCharPref("distribution.id", "");
- if (distId) {
- log("It is a distribution, not setting up nor enabling telemetry.");
- return;
- }
- } catch (e) {}
-
- log("Enabling telemetry for user");
- this.enableForUser = true;
- },
-};
-
-/**
- * Called when the add-on is installed.
- *
- * @param {Object} data Data about the add-on.
- * @param {Number} reason Indicates why the extension is being installed.
- */
-function install(data, reason) {
- // Nothing specifically to do, startup will set everything up for us.
-}
-
-/**
- * Called when the add-on is uninstalled.
- *
- * @param {Object} data Data about the add-on.
- * @param {Number} reason Indicates why the extension is being uninstalled.
- */
-function uninstall(data, reason) {
- // Nothing specifically to do, shutdown does what we need.
-}
-
-/**
- * Called when the add-on starts up.
- *
- * @param {Object} data Data about the add-on.
- * @param {Number} reason Indicates why the extension is being started.
- */
-function startup(data, reason) {
- try {
- gLoggingEnabled = Services.prefs.getBoolPref(PREF_LOGGING, false);
- } catch (e) {
- // Needed until Firefox 54
- }
-
- cohortManager.init();
-
- if (cohortManager.enableForUser) {
- // Workaround for bug 1202125
- // We need to delay our loading so that when we are upgraded,
- // our new script doesn't get the shutdown message.
- setTimeout(() => {
- activateTelemetry();
- }, 1000);
- }
-}
-
-/**
- * Called when the add-on shuts down.
- *
- * @param {Object} data Data about the add-on.
- * @param {Number} reason Indicates why the extension is being shut down.
- */
-function shutdown(data, reason) {
- // If we're shutting down, skip the cleanup to save time.
- if (reason === APP_SHUTDOWN) {
- return;
- }
-
- deactivateTelemetry();
-}
diff --git a/browser/extensions/followonsearch/content/followonsearch-fs.js b/browser/extensions/followonsearch/content/followonsearch-fs.js
deleted file mode 100644
index aaba382d0c86..000000000000
--- a/browser/extensions/followonsearch/content/followonsearch-fs.js
+++ /dev/null
@@ -1,308 +0,0 @@
-/* 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/. */
-
-/* eslint-env mozilla/frame-script */
-
-"use strict";
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyGlobalGetters(this, ["URLSearchParams"]);
-
-const kExtensionID = "followonsearch@mozilla.com";
-const kSaveTelemetryMsg = `${kExtensionID}:save-telemetry`;
-const kShutdownMsg = `${kExtensionID}:shutdown`;
-const kLastSearchQueueDepth = 10;
-
-/**
- * A map of search domains with their expected codes.
- */
-let searchDomains = [{
- "domains": [ "search.yahoo.co.jp" ],
- "search": "p",
- "followOnSearch": "ai",
- "prefix": ["fr"],
- "codes": ["mozff"],
- "sap": "yahoo",
-}, {
- "domains": [ "www.bing.com" ],
- "search": "q",
- "prefix": ["pc"],
- "reportPrefix": "form",
- "codes": ["MOZI", "MOZD", "MZSL01", "MZSL02", "MZSL03", "MOZ2"],
- "sap": "bing",
-}, {
- // The Google domains.
- "domains": [
- "www.google.com", "www.google.ac", "www.google.ad", "www.google.ae",
- "www.google.com.af", "www.google.com.ag", "www.google.com.ai",
- "www.google.al", "www.google.am", "www.google.co.ao", "www.google.com.ar",
- "www.google.as", "www.google.at", "www.google.com.au", "www.google.az",
- "www.google.ba", "www.google.com.bd", "www.google.be", "www.google.bf",
- "www.google.bg", "www.google.com.bh", "www.google.bi", "www.google.bj",
- "www.google.com.bn", "www.google.com.bo", "www.google.com.br",
- "www.google.bs", "www.google.bt", "www.google.co.bw", "www.google.by",
- "www.google.com.bz", "www.google.ca", "www.google.com.kh", "www.google.cc",
- "www.google.cd", "www.google.cf", "www.google.cat", "www.google.cg",
- "www.google.ch", "www.google.ci", "www.google.co.ck", "www.google.cl",
- "www.google.cm", "www.google.cn", "www.google.com.co", "www.google.co.cr",
- "www.google.com.cu", "www.google.cv", "www.google.cx", "www.google.com.cy",
- "www.google.cz", "www.google.de", "www.google.dj", "www.google.dk",
- "www.google.dm", "www.google.com.do", "www.google.dz", "www.google.com.ec",
- "www.google.ee", "www.google.com.eg", "www.google.es", "www.google.com.et",
- "www.google.eu", "www.google.fi", "www.google.com.fj", "www.google.fm",
- "www.google.fr", "www.google.ga", "www.google.ge", "www.google.gf",
- "www.google.gg", "www.google.com.gh", "www.google.com.gi", "www.google.gl",
- "www.google.gm", "www.google.gp", "www.google.gr", "www.google.com.gt",
- "www.google.gy", "www.google.com.hk", "www.google.hn", "www.google.hr",
- "www.google.ht", "www.google.hu", "www.google.co.id", "www.google.iq",
- "www.google.ie", "www.google.co.il", "www.google.im", "www.google.co.in",
- "www.google.io", "www.google.is", "www.google.it", "www.google.je",
- "www.google.com.jm", "www.google.jo", "www.google.co.jp", "www.google.co.ke",
- "www.google.ki", "www.google.kg", "www.google.co.kr", "www.google.com.kw",
- "www.google.kz", "www.google.la", "www.google.com.lb", "www.google.com.lc",
- "www.google.li", "www.google.lk", "www.google.co.ls", "www.google.lt",
- "www.google.lu", "www.google.lv", "www.google.com.ly", "www.google.co.ma",
- "www.google.md", "www.google.me", "www.google.mg", "www.google.mk",
- "www.google.ml", "www.google.com.mm", "www.google.mn", "www.google.ms",
- "www.google.com.mt", "www.google.mu", "www.google.mv", "www.google.mw",
- "www.google.com.mx", "www.google.com.my", "www.google.co.mz",
- "www.google.com.na", "www.google.ne", "www.google.nf", "www.google.com.ng",
- "www.google.com.ni", "www.google.nl", "www.google.no", "www.google.com.np",
- "www.google.nr", "www.google.nu", "www.google.co.nz", "www.google.com.om",
- "www.google.com.pk", "www.google.com.pa", "www.google.com.pe",
- "www.google.com.ph", "www.google.pl", "www.google.com.pg", "www.google.pn",
- "www.google.com.pr", "www.google.ps", "www.google.pt", "www.google.com.py",
- "www.google.com.qa", "www.google.ro", "www.google.rs", "www.google.ru",
- "www.google.rw", "www.google.com.sa", "www.google.com.sb", "www.google.sc",
- "www.google.se", "www.google.com.sg", "www.google.sh", "www.google.si",
- "www.google.sk", "www.google.com.sl", "www.google.sn", "www.google.sm",
- "www.google.so", "www.google.st", "www.google.sr", "www.google.com.sv",
- "www.google.td", "www.google.tg", "www.google.co.th", "www.google.com.tj",
- "www.google.tk", "www.google.tl", "www.google.tm", "www.google.to",
- "www.google.tn", "www.google.com.tr", "www.google.tt", "www.google.com.tw",
- "www.google.co.tz", "www.google.com.ua", "www.google.co.ug",
- "www.google.co.uk", "www.google.us", "www.google.com.uy", "www.google.co.uz",
- "www.google.com.vc", "www.google.co.ve", "www.google.vg", "www.google.co.vi",
- "www.google.com.vn", "www.google.vu", "www.google.ws", "www.google.co.za",
- "www.google.co.zm", "www.google.co.zw",
- ],
- "search": "q",
- "prefix": ["client"],
- "followOnSearch": "oq",
- "codes": ["firefox-b-ab", "firefox-b", "firefox-b-1-ab", "firefox-b-1"],
- "sap": "google",
-}, {
- // This is intended only for tests.
- "domains": [ "mochi.test" ],
- "search": "m",
- "prefix": ["mt"],
- "followOnSearch": "mtfo",
- "reportPrefix": "form",
- "codes": ["TEST"],
- "sap": "mochitest"
-}];
-
-function getSearchDomainCodes(host) {
- for (let domainInfo of searchDomains) {
- if (domainInfo.domains.includes(host)) {
- return domainInfo;
- }
- }
- return null;
-}
-
-/**
- * Used for debugging to log messages.
- *
- * @param {String} message The message to log.
- */
-function log(message) {
- // console.log(message);
-}
-
-// Hack to handle the most common reload/back/forward case.
-// If gLastSearchQueue includes the current URL, ignore the search.
-// This also prevents us from handling reloads with hashes twice
-let gLastSearchQueue = [];
-gLastSearchQueue.push = function(...args) {
- if (this.length >= kLastSearchQueueDepth) {
- this.shift();
- }
- return Array.prototype.push.apply(this, args);
-};
-
-// Track if we are in the middle of a Google session
-// that started from Firefox
-let searchingGoogle = false;
-
-/**
- * Since most codes are in the URL, we can handle them via
- * a progress listener.
- */
-var webProgressListener = {
- QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
- onLocationChange(aWebProgress, aRequest, aLocation, aFlags)
- {
- if (aWebProgress.DOMWindow && (aWebProgress.DOMWindow != content)) {
- return;
- }
- try {
- if (!aWebProgress.isTopLevel ||
- // Not a URL
- (!aLocation.schemeIs("http") && !aLocation.schemeIs("https")) ||
- // Doesn't have a query string or a ref
- (!aLocation.query && !aLocation.ref)) {
- searchingGoogle = false;
- return;
- }
- if (gLastSearchQueue.includes(aLocation.spec)) {
- // If it's a recent search, just return. We
- // don't reset searchingGoogle though because
- // we might still be doing that.
- return;
- }
- let domainInfo = getSearchDomainCodes(aLocation.host);
- if (!domainInfo) {
- searchingGoogle = false;
- return;
- }
-
- let queries = new URLSearchParams(aLocation.query);
- // Yahoo has switched to Unified search so we can get
- // different codes on the same domain. Hack for now
- // to allow two different prefixes for codes
- let code = queries.get(domainInfo.prefix[0]);
- if (!code && domainInfo.prefix.length > 1) {
- code = queries.get(domainInfo.prefix[1]);
- }
- // Special case Google so we can track searches
- // without codes from the browser.
- if (domainInfo.sap == "google") {
- if (aLocation.filePath == "/search") {
- gLastSearchQueue.push(aLocation.spec);
- // Our engine currently sends oe and ie - no one else does
- if (queries.get("oe") && queries.get("ie")) {
- sendSaveTelemetryMsg(code ? code : "none", code, "sap");
- searchingGoogle = true;
- } else {
- // The tbm value is the specific type of search (Books, Images, News, etc).
- // These are referred to as vertical searches.
- let tbm = queries.get("tbm");
- if (searchingGoogle) {
- sendSaveTelemetryMsg(code ? code : "none", code, "follow-on", tbm ? `vertical-${tbm}` : null);
- } else if (code) {
- // Trying to do the right thing for back button to existing entries
- sendSaveTelemetryMsg(code, domainInfo.sap, "follow-on", tbm ? `vertical-${tbm}` : null);
- }
- }
- }
- // Special case all Google. Otherwise our code can
- // show up in maps
- return;
- }
- searchingGoogle = false;
- if (queries.get(domainInfo.search)) {
- if (domainInfo.codes.includes(code)) {
- if (domainInfo.reportPrefix &&
- queries.get(domainInfo.reportPrefix)) {
- code = queries.get(domainInfo.reportPrefix);
- }
- if (queries.get(domainInfo.followOnSearch)) {
- log(`${aLocation.host} search with code ${code} - Follow on`);
- sendSaveTelemetryMsg(code, domainInfo.sap, "follow-on");
- } else {
- log(`${aLocation.host} search with code ${code} - First search via Firefox`);
- sendSaveTelemetryMsg(code, domainInfo.sap, "sap");
- }
- gLastSearchQueue.push(aLocation.spec);
- }
- }
- } catch (e) {
- console.error(e);
- }
- },
-};
-
-/**
- * Parses a cookie string into separate parts.
- *
- * @param {String} cookieString The string to parse.
- * @param {Object} [params] An optional object to append the parameters to.
- * @return {Object} An object containing the query keys and values.
- */
-function parseCookies(cookieString, params = {}) {
- var cookies = cookieString.split(/;\s*/);
-
- for (var i in cookies) {
- var kvp = cookies[i].split(/=(.+)/);
- params[kvp[0]] = kvp[1];
- }
-
- return params;
-}
-
-/**
- * Page load listener to handle loads www.bing.com only.
- * We have to use a page load listener because we need
- * to check cookies.
- * @param {Object} event The page load event.
- */
-function onPageLoad(event) {
- var doc = event.target;
- var win = doc.defaultView;
- if (win != win.top) {
- return;
- }
- var uri = doc.documentURIObject;
- if (!(uri instanceof Ci.nsIStandardURL) ||
- (!uri.schemeIs("http") && !uri.schemeIs("https")) ||
- uri.host != "www.bing.com" ||
- !doc.location.search ||
- gLastSearchQueue.includes(uri.spec)) {
- return;
- }
- var queries = new URLSearchParams(doc.location.search.toLowerCase());
- // For Bing, QBRE form code is used for all follow-on search
- if (queries.get("form") != "qbre") {
- return;
- }
- if (parseCookies(doc.cookie).SRCHS == "PC=MOZI") {
- log(`${uri.host} search with code MOZI - Follow on`);
- sendSaveTelemetryMsg("MOZI", "bing", "follow-on");
- gLastSearchQueue.push(uri.spec);
- }
-}
-
-/**
- * Sends a message to the process that added this script to tell it to save
- * telemetry.
- *
- * @param {String} code The codes used for the search engine.
- * @param {String} sap The SAP code.
- * @param {String} type The type of search (sap/follow-on).
- * @param {String} extra Any additional parameters (Optional)
- */
-function sendSaveTelemetryMsg(code, sap, type, extra) {
- sendAsyncMessage(kSaveTelemetryMsg, {
- code,
- sap,
- type,
- extra,
- });
-}
-
-addEventListener("DOMContentLoaded", onPageLoad, false);
-docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress)
- .addProgressListener(webProgressListener, Ci.nsIWebProgress.NOTIFY_LOCATION);
-
-let gDisabled = false;
-
-addMessageListener(kShutdownMsg, () => {
- if (!gDisabled) {
- removeEventListener("DOMContentLoaded", onPageLoad, false);
- docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress)
- .removeProgressListener(webProgressListener);
- gDisabled = true;
- }
-});
diff --git a/browser/extensions/followonsearch/install.rdf b/browser/extensions/followonsearch/install.rdf
deleted file mode 100644
index 971f8ed63889..000000000000
--- a/browser/extensions/followonsearch/install.rdf
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- followonsearch@mozilla.com
- Follow-on Search Telemetry
- 0.9.7
- 2
- true
- true
-
-
- {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
- 52.0
- 66.*
-
-
-
-
diff --git a/browser/extensions/followonsearch/jar.mn b/browser/extensions/followonsearch/jar.mn
deleted file mode 100644
index 8bad68630202..000000000000
--- a/browser/extensions/followonsearch/jar.mn
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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/.
-
-[features/followonsearch@mozilla.com] chrome.jar:
-% content followonsearch %content/
- content/ (content/*)
diff --git a/browser/extensions/followonsearch/moz.build b/browser/extensions/followonsearch/moz.build
deleted file mode 100644
index 4a95c67135c1..000000000000
--- a/browser/extensions/followonsearch/moz.build
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- 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/.
-
-with Files("**"):
- BUG_COMPONENT = ("Firefox", "Search")
-
-FINAL_TARGET_FILES.features['followonsearch@mozilla.com'] += [
- 'bootstrap.js',
- 'install.rdf',
-]
-
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
-
-JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/extensions/followonsearch/test/browser/.eslintrc.js b/browser/extensions/followonsearch/test/browser/.eslintrc.js
deleted file mode 100644
index 71818fe6506a..000000000000
--- a/browser/extensions/followonsearch/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "plugin:mozilla/browser-test",
- ],
-};
diff --git a/browser/extensions/followonsearch/test/browser/browser.ini b/browser/extensions/followonsearch/test/browser/browser.ini
deleted file mode 100644
index 434191379e92..000000000000
--- a/browser/extensions/followonsearch/test/browser/browser.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-
-[browser_followOnTelemetry.js]
-support-files =
- test.html
- test2.html
- testEngine.xml
diff --git a/browser/extensions/followonsearch/test/browser/browser_followOnTelemetry.js b/browser/extensions/followonsearch/test/browser/browser_followOnTelemetry.js
deleted file mode 100644
index f610f4d99c37..000000000000
--- a/browser/extensions/followonsearch/test/browser/browser_followOnTelemetry.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-ChromeUtils.defineModuleGetter(this, "SearchTestUtils",
- "resource://testing-common/SearchTestUtils.jsm");
-
-SearchTestUtils.init(Assert, registerCleanupFunction);
-
-const BASE_URL = "http://mochi.test:8888/browser/browser/extensions/followonsearch/test/browser/";
-const TEST_ENGINE_BASENAME = "testEngine.xml";
-
-add_task(async function test_followOnSearchTelemetry() {
- let engine = await SearchTestUtils.promiseNewSearchEngine(
- getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME,
- registerCleanupFunction);
- let oldCurrentEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- histogram.clear();
-
- registerCleanupFunction(() => Services.search.currentEngine = oldCurrentEngine);
-
- await BrowserTestUtils.withNewTab({gBrowser}, async browser => {
- // Open the initial search page via entering a search on the URL bar.
- let loadPromise = BrowserTestUtils.waitForLocationChange(gBrowser,
- `${BASE_URL}test.html?searchm=test&mt=TEST`);
-
- gURLBar.focus();
- EventUtils.sendString("test");
- EventUtils.sendKey("return");
-
- await loadPromise;
-
- // Perform a follow-on search, selecting the form in the page.
- loadPromise = BrowserTestUtils.waitForLocationChange(gBrowser,
- `${BASE_URL}test2.html?mtfo=followonsearchtest&mt=TEST&m=test`);
-
- await ContentTask.spawn(browser, null, function() {
- content.document.getElementById("submit").click();
- });
-
- await loadPromise;
-
- let snapshot;
-
- // We have to wait for the snapshot to come in, as there's async functionality
- // in the extension.
- await TestUtils.waitForCondition(() => {
- snapshot = histogram.snapshot();
- return "mochitest.follow-on:unknown:TEST" in snapshot;
- });
- Assert.ok("mochitest.follow-on:unknown:TEST" in snapshot,
- "Histogram should have an entry for the follow-on search.");
- Assert.deepEqual(snapshot["mochitest.follow-on:unknown:TEST"], {
- counts: [ 1, 0, 0 ],
- histogram_type: 4,
- max: 2,
- min: 1,
- ranges: [ 0, 1, 2 ],
- sum: 1,
- }, "Histogram should have the correct snapshot data");
- });
-});
diff --git a/browser/extensions/followonsearch/test/browser/test.html b/browser/extensions/followonsearch/test/browser/test.html
deleted file mode 100644
index e71568e1511b..000000000000
--- a/browser/extensions/followonsearch/test/browser/test.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Follow-on Search Test
-
-
-
-
-
diff --git a/browser/extensions/followonsearch/test/browser/test2.html b/browser/extensions/followonsearch/test/browser/test2.html
deleted file mode 100644
index 1c0987b7aa2e..000000000000
--- a/browser/extensions/followonsearch/test/browser/test2.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- Follow-on Search Test Final Page
-
-
-
diff --git a/browser/extensions/followonsearch/test/browser/testEngine.xml b/browser/extensions/followonsearch/test/browser/testEngine.xml
deleted file mode 100644
index b3c4e5ed1767..000000000000
--- a/browser/extensions/followonsearch/test/browser/testEngine.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- Mochitest
- Mochitest Engine
- UTF-8
- data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC
-
-
-
-
-
diff --git a/build/moz.configure/rust.configure b/build/moz.configure/rust.configure
index 5bb6b8715646..566351c406bb 100644
--- a/build/moz.configure/rust.configure
+++ b/build/moz.configure/rust.configure
@@ -289,6 +289,28 @@ cbindgen = check_prog('CBINDGEN', add_rustup_path('cbindgen'), paths=toolchain_s
when=depends(build_project)
(lambda build_project: build_project != 'js'))
+
+@depends_if(cbindgen)
+@checking('cbindgen version')
+@imports(_from='textwrap', _import='dedent')
+def cbindgen_version(cbindgen):
+ cbindgen_min_version = Version('0.6.1')
+
+ # cbindgen x.y.z
+ version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1])
+
+ if version < cbindgen_min_version:
+ die(dedent('''\
+ cbindgen version {} is too old. At least version {} is required.
+
+ Please update using 'cargo install cbindgen --force' or running
+ './mach bootstrap', after removing the existing executable located at
+ {}.
+ '''.format(version, cbindgen_min_version, cbindgen)))
+
+ return version
+
+
# Bindgen can use rustfmt to format Rust file, but it's not required.
js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program')
diff --git a/dom/media/VideoUtils.cpp b/dom/media/VideoUtils.cpp
index 8c1a6aeb4dd5..4a1363b91114 100644
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -747,10 +747,12 @@ CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
Maybe maybeWidth = aContainerType.ExtendedType().GetWidth();
if (maybeWidth && *maybeWidth > 0) {
videoInfo->mImage.width = *maybeWidth;
+ videoInfo->mDisplay.width = *maybeWidth;
}
Maybe maybeHeight = aContainerType.ExtendedType().GetHeight();
if (maybeHeight && *maybeHeight > 0) {
videoInfo->mImage.height = *maybeHeight;
+ videoInfo->mDisplay.height = *maybeHeight;
}
} else if (trackInfo->GetAsAudioInfo()) {
AudioInfo* audioInfo = trackInfo->GetAsAudioInfo();
diff --git a/dom/media/platforms/android/RemoteDataDecoder.cpp b/dom/media/platforms/android/RemoteDataDecoder.cpp
index 87604370bf6f..c938d39984f8 100644
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -208,6 +208,8 @@ public:
}
mIsCodecSupportAdaptivePlayback =
mJavaDecoder->IsAdaptivePlaybackSupported();
+ mIsHardwareAccelerated =
+ mJavaDecoder->IsHardwareAccelerated();
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
}
@@ -272,12 +274,19 @@ public:
return true;
}
+ bool IsHardwareAccelerated(nsACString& aFailureReason) const override
+ {
+ return mIsHardwareAccelerated;
+ }
+
private:
const VideoInfo mConfig;
GeckoSurface::GlobalRef mSurface;
AndroidSurfaceTextureHandle mSurfaceHandle;
// Only accessed on reader's task queue.
bool mIsCodecSupportAdaptivePlayback = false;
+ // Can be accessed on any thread, but only written on during init.
+ bool mIsHardwareAccelerated = false;
// Accessed on mTaskQueue, reader's TaskQueue and Java callback tread.
// SimpleMap however is thread-safe, so it's okay to do so.
SimpleMap mInputInfos;
@@ -457,8 +466,8 @@ RemoteDataDecoder::CreateVideoDecoder(const CreateDecoderParams& aParams,
MediaFormat::LocalRef format;
NS_ENSURE_SUCCESS(
MediaFormat::CreateVideoFormat(TranslateMimeType(config.mMimeType),
- config.mDisplay.width,
- config.mDisplay.height,
+ config.mImage.width,
+ config.mImage.height,
&format),
nullptr);
diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp
index 4fe6db006fa6..76c358027676 100644
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2530,6 +2530,43 @@ DrawBackgroundColor(nsCSSRendering::ImageLayerClipState& aClipState,
aCtx->Restore();
}
+static Maybe
+CalcScrollbarColor(nsIFrame* aFrame, StyleComplexColor nsStyleUI::* aColor)
+{
+ ComputedStyle* scrollbarStyle = nsLayoutUtils::StyleForScrollbar(aFrame);
+ auto color = scrollbarStyle->StyleUI()->*aColor;
+ if (color.IsAuto()) {
+ return Nothing();
+ }
+ return Some(color.CalcColor(scrollbarStyle));
+}
+
+static nscolor
+GetBackgroundColor(nsIFrame* aFrame, ComputedStyle* aComputedStyle)
+{
+ Maybe overrideColor = Nothing();
+ switch (aComputedStyle->StyleDisplay()->mAppearance) {
+ case StyleAppearance::ScrollbarthumbVertical:
+ case StyleAppearance::ScrollbarthumbHorizontal:
+ overrideColor =
+ CalcScrollbarColor(aFrame, &nsStyleUI::mScrollbarFaceColor);
+ break;
+ case StyleAppearance::ScrollbarVertical:
+ case StyleAppearance::ScrollbarHorizontal:
+ case StyleAppearance::Scrollcorner:
+ overrideColor =
+ CalcScrollbarColor(aFrame, &nsStyleUI::mScrollbarTrackColor);
+ break;
+ default:
+ break;
+ }
+ if (overrideColor.isSome()) {
+ return *overrideColor;
+ }
+ return aComputedStyle->
+ GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
+}
+
nscolor
nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
ComputedStyle* aComputedStyle,
@@ -2551,8 +2588,7 @@ nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
const nsStyleBackground *bg = aComputedStyle->StyleBackground();
nscolor bgColor;
if (aDrawBackgroundColor) {
- bgColor = aComputedStyle->
- GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
+ bgColor = GetBackgroundColor(aFrame, aComputedStyle);
if (NS_GET_A(bgColor) == 0) {
aDrawBackgroundColor = false;
}
diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp
index e66ad54cbfeb..c2abe2ab6176 100644
--- a/layout/xul/nsBox.cpp
+++ b/layout/xul/nsBox.cpp
@@ -522,6 +522,23 @@ nsIFrame::AddXULPrefSize(nsIFrame* aBox, nsSize& aSize, bool &aWidthSet, bool &a
return (aWidthSet && aHeightSet);
}
+// This returns the scrollbar width we want to use when either native
+// theme is disabled, or the native theme claims that it doesn't support
+// scrollbar.
+static nscoord
+GetScrollbarWidthNoTheme(nsIFrame* aBox)
+{
+ ComputedStyle* scrollbarStyle = nsLayoutUtils::StyleForScrollbar(aBox);
+ switch (scrollbarStyle->StyleUIReset()->mScrollbarWidth) {
+ default:
+ case StyleScrollbarWidth::Auto:
+ return 16 * AppUnitsPerCSSPixel();
+ case StyleScrollbarWidth::Thin:
+ return 8 * AppUnitsPerCSSPixel();
+ case StyleScrollbarWidth::None:
+ return 0;
+ }
+}
bool
nsIFrame::AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize,
@@ -548,6 +565,19 @@ nsIFrame::AddXULMinSize(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize& aSize,
aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height);
aHeightSet = true;
}
+ } else {
+ switch (display->mAppearance) {
+ case StyleAppearance::ScrollbarVertical:
+ aSize.width = GetScrollbarWidthNoTheme(aBox);
+ aWidthSet = true;
+ break;
+ case StyleAppearance::ScrollbarHorizontal:
+ aSize.height = GetScrollbarWidthNoTheme(aBox);
+ aHeightSet = true;
+ break;
+ default:
+ break;
+ }
}
}
diff --git a/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/media/ICodec.aidl b/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/media/ICodec.aidl
index d48eb47d0a57..3433542efa9b 100644
--- a/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/media/ICodec.aidl
+++ b/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/media/ICodec.aidl
@@ -15,6 +15,7 @@ interface ICodec {
void setCallbacks(in ICodecCallbacks callbacks);
boolean configure(in FormatParam format, in GeckoSurface surface, in int flags, in String drmStubId);
boolean isAdaptivePlaybackSupported();
+ boolean isHardwareAccelerated();
boolean isTunneledPlaybackSupported();
void start();
void stop();
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 8c97b4e68087..143a746e56b5 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
@@ -1046,16 +1046,6 @@ public class GeckoAppShell
return sScreenDepth;
}
- @WrapForJNI(calledFrom = "gecko")
- private static synchronized void setScreenDepthOverride(int aScreenDepth) {
- if (sScreenDepth != 0) {
- Log.e(LOGTAG, "Tried to override screen depth after it's already been set");
- throw new IllegalStateException();
- }
-
- sScreenDepth = aScreenDepth;
- }
-
@WrapForJNI(calledFrom = "gecko")
private static void performHapticFeedback(boolean aIsLongPress) {
// Don't perform haptic feedback if a vibration is currently playing,
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java
index 92b1164f7935..8e9d551e7896 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java
@@ -350,6 +350,7 @@ import org.mozilla.gecko.gfx.GeckoSurface;
private SamplePool mSamplePool;
// Values will be updated after configure called.
private volatile boolean mIsAdaptivePlaybackSupported = false;
+ private volatile boolean mIsHardwareAccelerated = false;
private boolean mIsTunneledPlaybackSupported = false;
public synchronized void setCallbacks(ICodecCallbacks callbacks) throws RemoteException {
@@ -399,6 +400,7 @@ import org.mozilla.gecko.gfx.GeckoSurface;
Log.w(LOGTAG, "unable to configure " + name + ". Try next.");
continue;
}
+ mIsHardwareAccelerated = !name.startsWith("OMX.google.");
mCodec = codec;
mInputProcessor = new InputProcessor();
final boolean renderToSurface = surface != null;
@@ -477,6 +479,11 @@ import org.mozilla.gecko.gfx.GeckoSurface;
return mIsAdaptivePlaybackSupported;
}
+ @Override
+ public synchronized boolean isHardwareAccelerated() {
+ return mIsHardwareAccelerated;
+ }
+
@Override
public synchronized boolean isTunneledPlaybackSupported() {
return mIsTunneledPlaybackSupported;
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java
index f5be498c8149..173862fee3ed 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java
@@ -191,6 +191,21 @@ public final class CodecProxy {
}
}
+ @WrapForJNI
+ public synchronized boolean isHardwareAccelerated()
+ {
+ if (mRemote == null) {
+ Log.e(LOGTAG, "cannot check isHardwareAccelerated with an ended codec");
+ return false;
+ }
+ try {
+ return mRemote.isHardwareAccelerated();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
@WrapForJNI
public synchronized boolean isTunneledPlaybackSupported()
{
diff --git a/netwerk/base/BackgroundFileSaver.cpp b/netwerk/base/BackgroundFileSaver.cpp
index 92e1a03efeb6..a48913ba67d3 100644
--- a/netwerk/base/BackgroundFileSaver.cpp
+++ b/netwerk/base/BackgroundFileSaver.cpp
@@ -490,10 +490,16 @@ BackgroundFileSaver::ProcessStateChange()
NS_ENSURE_SUCCESS(rv, rv);
}
- // Now we can update the actual target file name.
- mActualTarget = renamedTarget;
- mActualTargetKeepPartial = renamedTargetKeepPartial;
+ // We should not only update the mActualTarget with renameTarget when
+ // they point to the different files.
+ // In this way, if mActualTarget and renamedTarget point to the same file
+ // with different addresses, "CheckCompletion()" will return false forever.
}
+
+ // Update mActualTarget with renameTarget,
+ // even if they point to the same file.
+ mActualTarget = renamedTarget;
+ mActualTargetKeepPartial = renamedTargetKeepPartial;
}
// Notify if the target file name actually changed.
diff --git a/taskcluster/ci/test/raptor.yml b/taskcluster/ci/test/raptor.yml
index 4a0607a5fbb3..629cde615a3a 100644
--- a/taskcluster/ci/test/raptor.yml
+++ b/taskcluster/ci/test/raptor.yml
@@ -1,6 +1,7 @@
job-defaults:
max-run-time: 1800
suite: raptor
+ workdir: /home/cltbld
tier:
by-test-platform:
windows10-64-ccov/.*: 3
diff --git a/taskcluster/scripts/misc/build-cbindgen.sh b/taskcluster/scripts/misc/build-cbindgen.sh
index 9588fed6252b..3bfcc84993ab 100755
--- a/taskcluster/scripts/misc/build-cbindgen.sh
+++ b/taskcluster/scripts/misc/build-cbindgen.sh
@@ -1,6 +1,8 @@
#!/bin/bash
set -x -e -v
+# If you update this, make sure to update the minimum version in rust.configure
+# as well.
CBINDGEN_VERSION=v0.6.1
TARGET="$1"
diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py
index de54070ea602..c6208a08ecab 100644
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -19,6 +19,8 @@ from .taskgraph import TaskGraph
from .try_option_syntax import parse_message
from .actions import render_actions_json
from taskgraph.util.partials import populate_release_history
+from taskgraph.util.yaml import load_yaml
+
logger = logging.getLogger(__name__)
@@ -320,8 +322,7 @@ def write_artifact(filename, data):
def read_artifact(filename):
path = os.path.join(ARTIFACTS_DIR, filename)
if filename.endswith('.yml'):
- with open(path, 'r') as f:
- return yaml.load(f)
+ return load_yaml(path, filename)
elif filename.endswith('.json'):
with open(path, 'r') as f:
return json.load(f)
diff --git a/taskcluster/taskgraph/transforms/beetmover_geckoview.py b/taskcluster/taskgraph/transforms/beetmover_geckoview.py
index 518f9c5d95b2..99e41292cb31 100644
--- a/taskcluster/taskgraph/transforms/beetmover_geckoview.py
+++ b/taskcluster/taskgraph/transforms/beetmover_geckoview.py
@@ -69,7 +69,7 @@ def make_task_description(config, jobs):
'treeherder', {}).get('machine', {}).get('platform', '')
treeherder.setdefault('platform',
'{}/opt'.format(dep_th_platform))
- treeherder.setdefault('tier', 3)
+ treeherder.setdefault('tier', 2)
treeherder.setdefault('kind', 'build')
label = job['label']
description = (
diff --git a/taskcluster/taskgraph/transforms/job/mozharness_test.py b/taskcluster/taskgraph/transforms/job/mozharness_test.py
index 28b9f1521e1d..37d74b856f70 100644
--- a/taskcluster/taskgraph/transforms/job/mozharness_test.py
+++ b/taskcluster/taskgraph/transforms/job/mozharness_test.py
@@ -337,7 +337,8 @@ def mozharness_test_on_native_engine(config, job, taskdesc):
if test['max-run-time']:
worker['max-run-time'] = test['max-run-time']
- worker['env'] = env = {
+ env = worker.setdefault('env', {})
+ env.update({
'GECKO_HEAD_REPOSITORY': config.params['head_repository'],
'GECKO_HEAD_REV': config.params['head_rev'],
'MOZHARNESS_CONFIG': ' '.join(mozharness['config']),
@@ -351,7 +352,7 @@ def mozharness_test_on_native_engine(config, job, taskdesc):
"MOZ_HIDE_RESULTS_TABLE": '1',
"MOZ_NODE_PATH": "/usr/local/bin/node",
'MOZ_AUTOMATION': '1',
- }
+ })
# talos tests don't need Xvfb
if is_talos:
env['NEED_XVFB'] = 'false'
diff --git a/taskcluster/taskgraph/transforms/tests.py b/taskcluster/taskgraph/transforms/tests.py
index 21ede56f39fc..544a67bd012d 100644
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -146,6 +146,9 @@ test_description_schema = Schema({
'test-platform',
basestring),
+ # base work directory used to set up the task.
+ Optional('workdir'): basestring,
+
# the name by which this test suite is addressed in try syntax; defaults to
# the test-name. This will translate to the `unittest_try_name` or
# `talos_try_name` attribute.
@@ -1097,6 +1100,9 @@ def make_job_description(config, tests):
run['using'] = 'mozharness-test'
run['test'] = test
+ if 'workdir' in test:
+ run['workdir'] = test.pop('workdir')
+
jobdesc['worker-type'] = test.pop('worker-type')
if test.get('fetches'):
jobdesc['fetches'] = test.pop('fetches')
diff --git a/testing/mozharness/mozharness/mozilla/fetches.py b/testing/mozharness/mozharness/mozilla/fetches.py
new file mode 100644
index 000000000000..15090858f58e
--- /dev/null
+++ b/testing/mozharness/mozharness/mozilla/fetches.py
@@ -0,0 +1,59 @@
+# 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/.
+
+import os
+from distutils.spawn import find_executable
+
+import mozfile
+
+ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{task}/artifacts/{artifact}'
+
+
+class FetchesMixin(object):
+ """Utility class to download artifacts via `MOZ_FETCHES` and the
+ `fetch-content` script."""
+
+ @property
+ def fetch_script(self):
+ if getattr(self, '_fetch_script', None):
+ return self._fetch_script
+
+ self._fetch_script = find_executable('fetch-content')
+ if not self._fetch_script and 'GECKO_PATH' in os.environ:
+ self._fetch_script = os.path.join(os.environ['GECKO_PATH'],
+ 'taskcluster', 'script', 'misc', 'fetch-content')
+ return self._fetch_script
+
+ def fetch_content(self):
+ if not os.environ.get('MOZ_FETCHES'):
+ self.warning('no fetches to download')
+ return
+
+ fetches = os.environ['MOZ_FETCHES'].split()
+
+ if not self.fetch_script or not os.path.isfile(self.fetch_script):
+ self.warning("fetch-content script not found, downloading manually")
+ self._download_fetches(fetches)
+ return
+
+ cmd = [self.fetch_script, 'task-artifacts'] + fetches
+ self.run_command(cmd, env=os.environ, throw_exception=True)
+
+ def _download_fetches(self, fetches):
+ # TODO: make sure fetch-content script is available everywhere
+ # so this isn't needed
+ for word in fetches:
+ artifact, task = word.split('@', 1)
+ extdir = os.environ['MOZ_FETCHES_DIR']
+
+ if '>' in artifact:
+ artifact, subdir = artifact.rsplit('>', 1)
+ extdir = os.path.join(extdir, subdir)
+
+ url = ARTIFACT_URL.format(artifact=artifact, task=task)
+ self.download_file(url)
+
+ filename = os.path.basename(artifact)
+ mozfile.extract(filename, extdir)
+ os.remove(filename)
diff --git a/testing/mozharness/mozharness/mozilla/testing/codecoverage.py b/testing/mozharness/mozharness/mozilla/testing/codecoverage.py
index 5ac405fc1894..3370ab8bb4a0 100644
--- a/testing/mozharness/mozharness/mozilla/testing/codecoverage.py
+++ b/testing/mozharness/mozharness/mozilla/testing/codecoverage.py
@@ -8,7 +8,6 @@ import os
import posixpath
import shutil
import sys
-import tarfile
import tempfile
import zipfile
import uuid
@@ -144,31 +143,14 @@ class CodeCoverageMixin(SingleTestMixin):
self.java_coverage_output_path = os.path.join(tempfile.mkdtemp(),
'junit-coverage.ec')
- def _download_grcov(self):
- fetches_dir = os.environ.get('MOZ_FETCHES_DIR')
- if fetches_dir and os.path.isfile(os.path.join(fetches_dir, 'grcov')):
- self.grcov_dir = fetches_dir
- else:
- # Create the grcov directory, then download it.
- # TODO: use the fetch-content script to download artifacts.
- self.grcov_dir = tempfile.mkdtemp()
- ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{task}/artifacts/{artifact}'
- for word in os.getenv('MOZ_FETCHES').split():
- artifact, task = word.split('@', 1)
- filename = os.path.basename(artifact)
- url = ARTIFACT_URL.format(artifact=artifact, task=task)
- self.download_file(url, parent_dir=self.grcov_dir)
-
- with tarfile.open(os.path.join(self.grcov_dir, filename), 'r') as tar:
- tar.extractall(self.grcov_dir)
- os.remove(os.path.join(self.grcov_dir, filename))
-
@PostScriptAction('download-and-extract')
def setup_coverage_tools(self, action, success=None):
if not self.code_coverage_enabled and not self.java_code_coverage_enabled:
return
- self._download_grcov()
+ self.grcov_dir = os.environ['MOZ_FETCHES_DIR']
+ if not os.path.isfile(os.path.join(self.grcov_dir, 'grcov')):
+ self.fetch_content()
if self.code_coverage_enabled:
self._setup_cpp_js_coverage_tools()
diff --git a/testing/mozharness/mozharness/mozilla/testing/per_test_base.py b/testing/mozharness/mozharness/mozilla/testing/per_test_base.py
index 2fa9fb8c8eb4..fb82beac1012 100644
--- a/testing/mozharness/mozharness/mozilla/testing/per_test_base.py
+++ b/testing/mozharness/mozharness/mozilla/testing/per_test_base.py
@@ -13,8 +13,10 @@ import sys
import mozinfo
from manifestparser import TestManifest
+from mozharness.mozilla.fetches import FetchesMixin
-class SingleTestMixin(object):
+
+class SingleTestMixin(FetchesMixin):
"""Utility functions for per-test testing like test verification and per-test coverage."""
def __init__(self):
diff --git a/testing/mozharness/mozharness/mozilla/testing/raptor.py b/testing/mozharness/mozharness/mozilla/testing/raptor.py
index 0cec719c8765..09b7009890f6 100644
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py
+++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py
@@ -299,6 +299,8 @@ class Raptor(TestingMixin, MercurialScript, CodeCoverageMixin):
# clobber defined in BaseScript
def download_and_extract(self, extract_dirs=None, suite_categories=None):
+ if 'MOZ_FETCHES' in os.environ:
+ self.fetch_content()
return super(Raptor, self).download_and_extract(
suite_categories=['common', 'raptor']
)
diff --git a/testing/mozharness/mozharness/mozilla/testing/testbase.py b/testing/mozharness/mozharness/mozilla/testing/testbase.py
index 9bb888c0f227..127597d15e67 100755
--- a/testing/mozharness/mozharness/mozilla/testing/testbase.py
+++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py
@@ -20,6 +20,7 @@ from mozharness.base.python import (
virtualenv_config_options,
)
from mozharness.mozilla.automation import AutomationMixin, TBPL_WARNING
+from mozharness.mozilla.fetches import FetchesMixin
from mozharness.mozilla.structuredlog import StructuredOutputParser
from mozharness.mozilla.testing.unittest import DesktopUnittestOutputParser
from mozharness.mozilla.testing.try_tools import TryToolsMixin, try_config_options
@@ -102,7 +103,7 @@ testing_config_options = [
# TestingMixin {{{1
class TestingMixin(VirtualenvMixin, AutomationMixin, ResourceMonitoringMixin,
- TooltoolMixin, TryToolsMixin, VerifyToolsMixin):
+ TooltoolMixin, TryToolsMixin, VerifyToolsMixin, FetchesMixin):
"""
The steps to identify + download the proper bits for [browser] unit
tests and Talos.
diff --git a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
index 9e589323bd7c..c97e362518fe 100644
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -11,6 +11,9 @@ ChromeUtils.import("resource://gre/modules/ActorManagerParent.jsm");
ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+// Windowless browsers can create documents that rely on XUL Custom Elements:
+ChromeUtils.import("resource://gre/modules/CustomElementsListener.jsm", null);
+
ChromeUtils.defineModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
ChromeUtils.defineModuleGetter(this, "AddonTestUtils",
diff --git a/toolkit/components/processsingleton/CustomElementsListener.jsm b/toolkit/components/processsingleton/CustomElementsListener.jsm
new file mode 100644
index 000000000000..812907692343
--- /dev/null
+++ b/toolkit/components/processsingleton/CustomElementsListener.jsm
@@ -0,0 +1,22 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+// Set up Custom Elements for XUL and XHTML documents before anything else
+// happens. Anything loaded here should be considered part of core XUL functionality.
+// Any window-specific elements can be registered via