diff --git a/.eslintignore b/.eslintignore index fca8c2651f54..c1f0da558791 100644 --- a/.eslintignore +++ b/.eslintignore @@ -220,3 +220,6 @@ tools/tryselect/selectors/chooser/templates/chooser.html # Ignore preprocessed *(P)refs.js files in update-packaging. tools/update-packaging/**/*refs.js + +# Ignore backgroundtasks preferences files. +toolkit/components/backgroundtasks/defaults diff --git a/.prettierignore b/.prettierignore index 24fd18b7f33f..c4b4c32638c9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -58,3 +58,6 @@ devtools/client/debugger/src/test/mochitest/examples/ember/quickstart # These are source mapped and the locations are asserted in the test case. devtools/client/webconsole/test/browser/test-mangled-function.* + +# Ignore backgroundtasks preferences files. +toolkit/components/backgroundtasks/defaults diff --git a/browser/base/content/test/static/browser_all_files_referenced.js b/browser/base/content/test/static/browser_all_files_referenced.js index eb9a7fcd4579..7b20d7d34502 100644 --- a/browser/base/content/test/static/browser_all_files_referenced.js +++ b/browser/base/content/test/static/browser_all_files_referenced.js @@ -56,6 +56,8 @@ if (AppConstants.platform == "macosx") { } if (AppConstants.MOZ_BACKGROUNDTASKS) { + // These preferences are active only when we're in background task mode. + gExceptionPaths.push("resource://gre/defaults/backgroundtasks/"); // `BackgroundTask_id.jsm` is loaded at runtime by `app --backgroundtask id ...`. gExceptionPaths.push("resource://gre/modules/backgroundtasks/"); } diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index b861ad214a64..ad725c5114b0 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -98,6 +98,10 @@ ifdef MOZ_DEFAULT_BROWSER_AGENT DEFINES += -DMOZ_DEFAULT_BROWSER_AGENT=1 endif +ifdef MOZ_BACKGROUNDTASKS +DEFINES += -DMOZ_BACKGROUNDTASKS=1 +endif + ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) MOZ_PKG_MAC_DSSTORE=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/dsstore MOZ_PKG_MAC_BACKGROUND=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/background.png diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index f060c457cee2..ec20499166e8 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -305,6 +305,12 @@ ; gre location for now. @RESPATH@/defaults/pref/channel-prefs.js +; Background tasks-specific preferences. These are in the GRE +; location since they apply to all tasks at this time. +#ifdef MOZ_BACKGROUNDTASKS +@RESPATH@/defaults/backgroundtasks/backgroundtasks.js +#endif + ; [Layout Engine Resources] ; Style Sheets, Graphics and other Resources used by the layout engine. @RESPATH@/res/EditorOverride.css diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index cfc498d5c250..2a7f5bacbd83 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -86,6 +86,9 @@ #include "plstr.h" #include "prlink.h" #include "xpcpublic.h" +#ifdef MOZ_BACKGROUNDTASKS +# include "mozilla/BackgroundTasks.h" +#endif #ifdef DEBUG # include @@ -4530,6 +4533,13 @@ nsresult Preferences::InitInitialObjects(bool aIsStartup) { rv = pref_ReadDefaultPrefs(jarReader, "defaults/pref/*.js$"); NS_ENSURE_SUCCESS(rv, rv); +#ifdef MOZ_BACKGROUNDTASKS + if (BackgroundTasks::IsBackgroundTaskMode()) { + rv = pref_ReadDefaultPrefs(jarReader, "defaults/backgroundtasks/*.js$"); + NS_ENSURE_SUCCESS(rv, rv); + } +#endif + #ifdef MOZ_WIDGET_ANDROID // Load jar:$gre/omni.jar!/defaults/pref/$MOZ_ANDROID_CPU_ABI/*.js. nsAutoCString path; @@ -4609,6 +4619,25 @@ nsresult Preferences::InitInitialObjects(bool aIsStartup) { NS_WARNING("Error parsing preferences."); } } + +#ifdef MOZ_BACKGROUNDTASKS + if (BackgroundTasks::IsBackgroundTaskMode()) { + rv = appJarReader->FindInit("defaults/backgroundtasks/*.js$", + getter_Transfers(find)); + NS_ENSURE_SUCCESS(rv, rv); + prefEntries.Clear(); + while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) { + prefEntries.AppendElement(Substring(entryName, entryNameLen)); + } + prefEntries.Sort(); + for (uint32_t i = prefEntries.Length(); i--;) { + rv = pref_ReadPrefFromJar(appJarReader, prefEntries[i].get()); + if (NS_FAILED(rv)) { + NS_WARNING("Error parsing preferences."); + } + } + } +#endif } nsCOMPtr dirSvc( diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build index 9273ab29dc99..d0ccfcff6609 100644 --- a/modules/libpref/moz.build +++ b/modules/libpref/moz.build @@ -167,3 +167,6 @@ else: FINAL_TARGET_PP_FILES += [ "greprefs.js", ] + +if CONFIG["MOZ_BACKGROUNDTASKS"]: + DEFINES["MOZ_BACKGROUNDTASKS"] = True diff --git a/toolkit/components/backgroundtasks/defaults/backgroundtasks.js b/toolkit/components/backgroundtasks/defaults/backgroundtasks.js new file mode 100644 index 000000000000..a52c1b117873 --- /dev/null +++ b/toolkit/components/backgroundtasks/defaults/backgroundtasks.js @@ -0,0 +1,27 @@ +/* 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/. */ + +pref("browser.dom.window.dump.enabled", true); +pref("devtools.console.stdout.chrome", true); + +pref("network.process.enabled", false); + +pref("toolkit.telemetry.archive.enabled", false); +pref("toolkit.telemetry.firstShutdownPing.enabled", false); +pref("toolkit.telemetry.healthping.enabled", false); +pref("toolkit.telemetry.newProfilePing.enabled", false); +pref("toolkit.telemetry.eventping.enabled", false); +pref("toolkit.telemetry.ecosystemtelemetry.enabled", false); +pref("toolkit.telemetry.prioping.enabled", false); +pref("datareporting.policy.dataSubmissionEnabled", false); +pref("datareporting.healthreport.uploadEnabled", false); + +pref("browser.cache.offline.enable", false); +pref("browser.cache.offline.storage.enable", false); +pref("browser.cache.disk.enable", false); +pref("permissions.memory_only", true); + +// For testing only: used to test that backgroundtask-specific prefs are +// processed. This just needs to be an unusual integer in the range 0..127. +pref("test.backgroundtask_specific_pref.exitCode", 79); diff --git a/toolkit/components/backgroundtasks/moz.build b/toolkit/components/backgroundtasks/moz.build index 9173bdced63c..39bd3bd04f81 100644 --- a/toolkit/components/backgroundtasks/moz.build +++ b/toolkit/components/backgroundtasks/moz.build @@ -37,4 +37,13 @@ EXTRA_JS_MODULES.backgroundtasks += [ "BackgroundTask_success.jsm", ] +BROWSER_CHROME_MANIFESTS += ["tests/browser/browser.ini"] XPCSHELL_TESTS_MANIFESTS += ["tests/xpcshell/xpcshell.ini"] + +TESTING_JS_MODULES.backgroundtasks += [ + "tests/BackgroundTask_backgroundtask_specific_pref.jsm", +] + +FINAL_TARGET_FILES.defaults.backgroundtasks += [ + "defaults/backgroundtasks.js", +] diff --git a/toolkit/components/backgroundtasks/tests/BackgroundTask_backgroundtask_specific_pref.jsm b/toolkit/components/backgroundtasks/tests/BackgroundTask_backgroundtask_specific_pref.jsm new file mode 100644 index 000000000000..0fa900f04f5e --- /dev/null +++ b/toolkit/components/backgroundtasks/tests/BackgroundTask_backgroundtask_specific_pref.jsm @@ -0,0 +1,23 @@ +/* -*- 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/. */ + +var EXPORTED_SYMBOLS = ["runBackgroundTask"]; + +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +async function runBackgroundTask(commandLine) { + let pref = commandLine.length + ? commandLine.getArgument(0) + : "test.backgroundtask_specific_pref.exitCode"; + + // 0, 1, 2, 3 are all meaningful exit codes already. + let exitCode = Services.prefs.getIntPref(pref, 4); + + console.error( + `runBackgroundTask: backgroundtask_specific_pref read pref '${pref}', exiting with exitCode ${exitCode}` + ); + + return exitCode; +} diff --git a/toolkit/components/backgroundtasks/tests/browser/browser.ini b/toolkit/components/backgroundtasks/tests/browser/browser.ini new file mode 100644 index 000000000000..aed80c744448 --- /dev/null +++ b/toolkit/components/backgroundtasks/tests/browser/browser.ini @@ -0,0 +1,9 @@ +# 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/. + +[DEFAULT] +skip-if = toolkit == 'android' +head = head.js + +[browser_backgroundtask_specific_pref.js] diff --git a/toolkit/components/backgroundtasks/tests/browser/browser_backgroundtask_specific_pref.js b/toolkit/components/backgroundtasks/tests/browser/browser_backgroundtask_specific_pref.js new file mode 100644 index 000000000000..b80ee2f59376 --- /dev/null +++ b/toolkit/components/backgroundtasks/tests/browser/browser_backgroundtask_specific_pref.js @@ -0,0 +1,23 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=4 ts=4 sts=4 et + * 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"; + +add_task(async function test_backgroundtask_specific_pref() { + // First, verify this pref isn't set in Gecko itself. + Assert.equal( + -1, + Services.prefs.getIntPref("test.backgroundtask_specific_pref.exitCode", -1) + ); + + // Second, verify that this pref is set in background tasks. + // mochitest-chrome tests locally test both unpackaged and packaged + // builds (with `--appname=dist`). + let exitCode = await do_backgroundtask("backgroundtask_specific_pref", { + extraArgs: ["test.backgroundtask_specific_pref.exitCode"], + }); + Assert.equal(79, exitCode); +}); diff --git a/toolkit/components/backgroundtasks/tests/browser/head.js b/toolkit/components/backgroundtasks/tests/browser/head.js new file mode 100644 index 000000000000..fb9c3fe123a0 --- /dev/null +++ b/toolkit/components/backgroundtasks/tests/browser/head.js @@ -0,0 +1,66 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=4 ts=4 sts=4 et + * 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"; + +async function do_backgroundtask( + task, + options = { extraArgs: [], extraEnv: {} } +) { + options = Object.assign({}, options); + options.extraArgs = options.extraArgs || []; + options.extraEnv = options.extraEnv || {}; + + let command = Services.dirsvc.get("XREExeF", Ci.nsIFile).path; + let args = ["--backgroundtask", task]; + args.push(...options.extraArgs); + + // Ensure `resource://testing-common` gets mapped. + let protocolHandler = Services.io + .getProtocolHandler("resource") + .QueryInterface(Ci.nsIResProtocolHandler); + + let uri = protocolHandler.getSubstitution("testing-common"); + Assert.ok(uri, "resource://testing-common is not substituted"); + + // The equivalent of _TESTING_MODULES_DIR in xpcshell. + options.extraEnv.XPCSHELL_TESTING_MODULES_URI = uri.spec; + + // Now we can actually invoke the process. + info( + `launching child process ${command} with args: ${args} and extra environment: ${JSON.stringify( + options.extraEnv + )}` + ); + + const { Subprocess } = ChromeUtils.import( + "resource://gre/modules/Subprocess.jsm" + ); + let proc = await Subprocess.call({ + command, + arguments: args, + environment: options.extraEnv, + environmentAppend: true, + stderr: "stdout", + }).then(p => { + p.stdin.close(); + const dumpPipe = async pipe => { + let data = await pipe.readString(); + while (data) { + for (let line of data.split(/\r\n|\r|\n/).slice(0, -1)) { + dump("> " + line + "\n"); + } + data = await pipe.readString(); + } + }; + dumpPipe(p.stdout); + + return p; + }); + + let { exitCode } = await proc.wait(); + return exitCode; +} diff --git a/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_specific_pref.js b/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_specific_pref.js new file mode 100644 index 000000000000..50f85b9becb7 --- /dev/null +++ b/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_specific_pref.js @@ -0,0 +1,20 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=4 ts=4 sts=4 et + * 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/. */ + +add_task(async function test_backgroundtask_specific_pref() { + // First, verify this pref isn't set in Gecko itself. + Assert.equal( + -1, + Services.prefs.getIntPref("test.backgroundtask_specific_pref.exitCode", -1) + ); + + // Second, verify that this pref is set in background tasks. + // xpcshell tests locally test unpackaged builds. + let exitCode = await do_backgroundtask("backgroundtask_specific_pref", { + extraArgs: ["test.backgroundtask_specific_pref.exitCode"], + }); + Assert.equal(79, exitCode); +}); diff --git a/toolkit/components/backgroundtasks/tests/xpcshell/xpcshell.ini b/toolkit/components/backgroundtasks/tests/xpcshell/xpcshell.ini index ea3f4f118e86..2dd493b2d678 100644 --- a/toolkit/components/backgroundtasks/tests/xpcshell/xpcshell.ini +++ b/toolkit/components/backgroundtasks/tests/xpcshell/xpcshell.ini @@ -8,5 +8,6 @@ support-files = CatBackgroundTaskRegistrationComponents.manifest [test_backgroundtask_exitcodes.js] +[test_backgroundtask_specific_pref.js] [test_manifest_with_backgroundtask.js] [test_manifest_without_backgroundtask.js] diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 59ec6e0510fa..c9ba0f294cb2 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -853,6 +853,10 @@ static nsresult DeleteDirIfExists(nsIFile* dir) { static const char* const kAppendPrefDir[] = {"defaults", "preferences", nullptr}; +#ifdef MOZ_BACKGROUNDTASKS +static const char* const kAppendBackgroundTasksPrefDir[] = { + "defaults", "backgroundtasks", nullptr}; +#endif nsresult nsXREDirProvider::GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult) { @@ -863,6 +867,12 @@ nsresult nsXREDirProvider::GetFilesInternal(const char* aProperty, nsCOMArray directories; LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories); +#ifdef MOZ_BACKGROUNDTASKS + if (mozilla::BackgroundTasks::IsBackgroundTaskMode()) { + LoadDirIntoArray(mGREDir, kAppendBackgroundTasksPrefDir, directories); + LoadDirIntoArray(mXULAppDir, kAppendBackgroundTasksPrefDir, directories); + } +#endif rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)); } else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST)) {