зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1675850 - Add MOZ_BACKGROUNDTASKS flag, {nsI}BackgroundTasks IDL and class. r=mossop,firefox-build-system-reviewers,mhentges
This adds a build flag (defaulting to on in Nightly builds) and an `AppConstants.jsm` definition. It lays the foundation for managing an active background task. A singleton, exposed as an XPCOM service, owns the task name and lives for the life of the application. This will be wired into the application startup path in future commits. It's separated to allow the changes to category registration to come early in the commit sequence. Differential Revision: https://phabricator.services.mozilla.com/D96481
This commit is contained in:
Родитель
0492d8333a
Коммит
7360317f0c
|
@ -0,0 +1,91 @@
|
|||
/* 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 "nsPrintfCString.h"
|
||||
#include "SpecialSystemDirectory.h"
|
||||
|
||||
#include "mozilla/BackgroundTasks.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackgroundTasks, nsIBackgroundTasks);
|
||||
|
||||
nsresult BackgroundTasks::GetOrCreateTemporaryProfileDirectoryImpl(
|
||||
nsIFile** aFile) {
|
||||
if (mBackgroundTask.isNothing()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
if (mProfD) {
|
||||
rv = mProfD->Clone(getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// We don't have the directory service at this point.
|
||||
rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// TODO: mix in the application hash and perhaps add some additional
|
||||
// randomness.
|
||||
rv = file->AppendNative(
|
||||
nsPrintfCString("backgroundtask-%s", mBackgroundTask.ref().get()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Make sure that the profile path exists and it's a directory.
|
||||
bool exists;
|
||||
rv = file->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!exists) {
|
||||
rv = file->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
bool isDir;
|
||||
rv = file->IsDirectory(&isDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!isDir) {
|
||||
return NS_ERROR_FILE_DESTINATION_NOT_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = file->Clone(getter_AddRefs(mProfD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsString path;
|
||||
file->GetPath(path);
|
||||
|
||||
file.forget(aFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BackgroundTasks::GetIsBackgroundTaskMode(bool* result) {
|
||||
*result = mBackgroundTask.isSome();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BackgroundTasks::BackgroundTaskName(nsAString& name) {
|
||||
name.SetIsVoid(true);
|
||||
if (mBackgroundTask.isSome()) {
|
||||
name.AssignASCII(mBackgroundTask.ref());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BackgroundTasks::OverrideBackgroundTaskNameForTesting(
|
||||
const nsAString& name) {
|
||||
if (name.IsVoid()) {
|
||||
mBackgroundTask = Nothing();
|
||||
} else {
|
||||
mBackgroundTask = Some(NS_LossyConvertUTF16toASCII(name));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::StaticRefPtr<BackgroundTasks> BackgroundTasks::sSingleton;
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,132 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 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/. */
|
||||
|
||||
#ifndef mozilla_BackgroundTasks_h
|
||||
#define mozilla_BackgroundTasks_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIBackgroundTasks.h"
|
||||
#include "nsICommandLine.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class BackgroundTasks final : public nsIBackgroundTasks {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIBACKGROUNDTASKS
|
||||
|
||||
public:
|
||||
explicit BackgroundTasks(Maybe<nsCString> aBackgroundTask)
|
||||
: mBackgroundTask(aBackgroundTask) {}
|
||||
|
||||
static void Init(Maybe<nsCString> aBackgroundTask) {
|
||||
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MOZ_RELEASE_ASSERT(!sSingleton,
|
||||
"BackgroundTasks singleton already initialized");
|
||||
sSingleton = new BackgroundTasks(aBackgroundTask);
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
|
||||
static void Shutdown() {
|
||||
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
if (!sSingleton) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sSingleton->mProfD) {
|
||||
sSingleton->mProfD->Remove(/* aRecursive */ true);
|
||||
}
|
||||
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a raw pointer to the singleton instance. Use this accessor in C++
|
||||
* code that just wants to call a method on the instance, but does not need to
|
||||
* hold a reference.
|
||||
*/
|
||||
static BackgroundTasks* GetSingleton() {
|
||||
if (!sSingleton) {
|
||||
// xpcshell doesn't set up background tasks: default to no background
|
||||
// task.
|
||||
Init(Nothing());
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(
|
||||
sSingleton, "BackgroundTasks singleton should have been initialized");
|
||||
|
||||
return sSingleton.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an addRef'd pointer to the singleton instance. This is used by the
|
||||
* XPCOM constructor that exists to support usage from JS.
|
||||
*/
|
||||
static already_AddRefed<BackgroundTasks> GetSingletonAddRefed() {
|
||||
return RefPtr<BackgroundTasks>(GetSingleton()).forget();
|
||||
}
|
||||
|
||||
static const Maybe<nsCString> GetBackgroundTasks() {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
return GetSingleton()->mBackgroundTask;
|
||||
}
|
||||
|
||||
static bool IsBackgroundTaskMode() {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetBackgroundTasks().isSome();
|
||||
}
|
||||
|
||||
static nsresult GetOrCreateTemporaryProfileDirectory(nsIFile** aFile) {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return GetSingleton()->GetOrCreateTemporaryProfileDirectoryImpl(aFile);
|
||||
}
|
||||
|
||||
static nsresult RunBackgroundTask(nsICommandLine* aCmdLine) {
|
||||
Maybe<nsCString> task = GetBackgroundTasks();
|
||||
if (task.isNothing()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// For now, do nothing.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
static StaticRefPtr<BackgroundTasks> sSingleton;
|
||||
|
||||
Maybe<nsCString> mBackgroundTask;
|
||||
nsCOMPtr<nsIFile> mProfD;
|
||||
|
||||
nsresult GetOrCreateTemporaryProfileDirectoryImpl(nsIFile** aFile);
|
||||
|
||||
virtual ~BackgroundTasks() = default;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_BackgroundTasks_h
|
|
@ -0,0 +1,13 @@
|
|||
Classes = [
|
||||
{
|
||||
'cid': '{cdc33a1f-e8ae-4a4f-85d0-6ec633fe872c}',
|
||||
'contract_ids': [
|
||||
'@mozilla.org/backgroundtasks;1',
|
||||
],
|
||||
'type': 'BackgroundTasks',
|
||||
'singleton': True,
|
||||
'constructor': 'BackgroundTasks::GetSingletonAddRefed',
|
||||
'headers': ['mozilla/BackgroundTasks.h'],
|
||||
'processes': ProcessSelector.ANY_PROCESS,
|
||||
},
|
||||
]
|
|
@ -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/.
|
||||
|
||||
with Files("**"):
|
||||
# TODO: House this somewhere more specific?
|
||||
BUG_COMPONENT = ("Toolkit", "Startup and Profile System")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"BackgroundTasks.cpp",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
"BackgroundTasks.h",
|
||||
]
|
||||
|
||||
XPCOM_MANIFESTS += [
|
||||
"components.conf",
|
||||
]
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
"nsIBackgroundTasks.idl",
|
||||
]
|
||||
|
||||
XPIDL_MODULE = "toolkit_backgroundtasks"
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* Determine if this instance is running background task mode and
|
||||
* what, if any, task is active.
|
||||
*/
|
||||
[scriptable, uuid(353dccb8-a863-49e4-941b-007382eac168)]
|
||||
interface nsIBackgroundTasks : nsISupports
|
||||
{
|
||||
/**
|
||||
* True if and only if this invocation is running in background task mode.
|
||||
*/
|
||||
readonly attribute boolean isBackgroundTaskMode;
|
||||
|
||||
/**
|
||||
* A non-empty task name if this invocation is running in background
|
||||
* task mode, or `null` if this invocation is not running in
|
||||
* background task mode.
|
||||
*/
|
||||
AString backgroundTaskName();
|
||||
|
||||
/**
|
||||
* Should only be used for testing.
|
||||
* Set the background task name.
|
||||
*/
|
||||
void overrideBackgroundTaskNameForTesting(in AString taskName);
|
||||
};
|
|
@ -129,6 +129,9 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] != "android":
|
|||
if CONFIG["MOZ_BUILD_APP"] == "browser":
|
||||
DIRS += ["normandy", "messaging-system"]
|
||||
|
||||
if CONFIG["MOZ_BACKGROUNDTASKS"]:
|
||||
DIRS += ["backgroundtasks"]
|
||||
|
||||
# This is only packaged for browser since corrupt JAR and XPI files tend to be a desktop-OS problem.
|
||||
if CONFIG["MOZ_BUILD_APP"] == "browser":
|
||||
DIRS += ["corroborator"]
|
||||
|
|
|
@ -219,6 +219,13 @@ this.AppConstants = Object.freeze({
|
|||
false,
|
||||
#endif
|
||||
|
||||
MOZ_BACKGROUNDTASKS:
|
||||
#ifdef MOZ_BACKGROUNDTASKS
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_UPDATE_AGENT:
|
||||
#ifdef MOZ_UPDATE_AGENT
|
||||
true,
|
||||
|
|
|
@ -292,6 +292,7 @@ for var in (
|
|||
|
||||
for var in (
|
||||
"MOZ_ALLOW_ADDON_SIDELOAD",
|
||||
"MOZ_BACKGROUNDTASKS",
|
||||
"MOZ_SYSTEM_NSS",
|
||||
"MOZ_UNSIGNED_APP_SCOPE",
|
||||
"MOZ_UNSIGNED_SYSTEM_SCOPE",
|
||||
|
|
|
@ -2495,3 +2495,20 @@ def oxidized_breakpad(target):
|
|||
|
||||
set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
|
||||
set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
|
||||
|
||||
|
||||
# Enable or disable running in background task mode: headless for
|
||||
# periodic, short-lived, maintenance tasks.
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
option(
|
||||
"--enable-backgroundtasks",
|
||||
default=milestone.is_nightly,
|
||||
help="{Enable|Disable} running in background task mode",
|
||||
)
|
||||
|
||||
|
||||
set_config(
|
||||
"MOZ_BACKGROUNDTASKS", depends_if("--enable-backgroundtasks")(lambda _: True)
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче