# HG changeset patch # User Fernando Jimenez # Parent 4b7cac6613e1331df33d80fd3af40d568e64d63d Bug 1217544 - Implement one-off BackgroundSync API. Part 1: BackgroundSync interface. r=baku diff --git a/dom/backgroundsync/BackgroundSync.cpp b/dom/backgroundsync/BackgroundSync.cpp new file mode 100644 --- /dev/null +++ b/dom/backgroundsync/BackgroundSync.cpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "BackgroundSync.h" + +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/PromiseWorkerProxy.h" +#include "mozilla/dom/BackgroundSyncBinding.h" +#include "mozilla/ipc/BackgroundChild.h" +#include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/ipc/PBackgroundChild.h" +#include "mozilla/Preferences.h" +#include "nsIGlobalObject.h" +#include "WorkerPrivate.h" + +namespace mozilla { + +using namespace ipc; + +namespace dom { + +using namespace workers; + +namespace backgroundsync { + +// BackgroundSync + +// static +already_AddRefed +BackgroundSync::CreateOnMainThread(nsIGlobalObject* aGlobal, + nsIPrincipal* aPrincipal, + ErrorResult& aRv) +{ + MOZ_ASSERT(aGlobal); + MOZ_ASSERT(aPrincipal); + MOZ_ASSERT(NS_IsMainThread()); + + PrincipalInfo principalInfo; + nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return nullptr; + } + + RefPtr ref = new BackgroundSync(aGlobal, principalInfo); + return ref.forget(); +} + +// static +already_AddRefed +BackgroundSync::CreateOnWorker(WorkerPrivate* aWorkerPrivate) +{ + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + + const PrincipalInfo& principalInfo = aWorkerPrivate->GetPrincipalInfo(); + + RefPtr ref = new BackgroundSync(nullptr, + principalInfo); + return ref.forget(); +} + +BackgroundSync::BackgroundSync(nsIGlobalObject* aGlobal, + const PrincipalInfo& aPrincipalInfo) + : mGlobal(aGlobal) + , mPrincipalInfo(new PrincipalInfo(aPrincipalInfo)) +{} + +BackgroundSync::~BackgroundSync() +{} + +// Bindings methods. + +JSObject* +BackgroundSync::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return mozilla::dom::BackgroundSyncBinding::Wrap(aCx, this, aGivenProto); +} + +// static +bool +BackgroundSync::PrefEnabled(JSContext* aCx, JSObject* aObj) +{ + using mozilla::dom::workers::WorkerPrivate; + using mozilla::dom::workers::GetWorkerPrivateFromContext; + + // If we are on the main thread, then check the pref directly. + if (NS_IsMainThread()) { + return Preferences::GetBool("dom.background.sync.enabled", false); + } + + // Otherwise check the pref via the worker private helper. + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx); + if (!workerPrivate) { + return false; + } + + return workerPrivate->BackgroundSyncEnabled(); +} + +// WebIDL interace methods. + +already_AddRefed +BackgroundSync::Register(const nsAString& aName, ErrorResult& aRv) +{ + RefPtr p = Promise::Create(mGlobal, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + return p.forget(); +} + +already_AddRefed +BackgroundSync::GetTags(ErrorResult& aRv) +{ + RefPtr p = Promise::Create(mGlobal, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + return p.forget(); +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BackgroundSync, mGlobal) +NS_IMPL_CYCLE_COLLECTING_ADDREF(BackgroundSync) +NS_IMPL_CYCLE_COLLECTING_RELEASE(BackgroundSync) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BackgroundSync) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +} // namespace backgroundsync +} // namespace dom +} // namespace mozilla diff --git a/dom/backgroundsync/BackgroundSync.h b/dom/backgroundsync/BackgroundSync.h new file mode 100644 --- /dev/null +++ b/dom/backgroundsync/BackgroundSync.h @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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_dom_BackgroundSync_h +#define mozilla_dom_BackgroundSync_h + +#include "jsapi.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "nsCOMPtr.h" +#include "nsWrapperCache.h" + +class nsIGlobalObject; +class nsIPrincipal; + +namespace mozilla { + +namespace ipc { + class PrincipalInfo; +} // namespace ipc + +namespace dom { + +namespace workers { + class WorkerPrivate; +} // namespace workers + +class Promise; + +namespace backgroundsync { + +class BackgroundSync final : public nsISupports + , public nsWrapperCache +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BackgroundSync) + + static already_AddRefed + CreateOnMainThread(nsIGlobalObject* aGlobal, + nsIPrincipal* aPrincipal, + ErrorResult& aRv); + + static already_AddRefed + CreateOnWorker(workers::WorkerPrivate* aWorkerPrivate); + + // Binding methods. + + nsIGlobalObject* + GetParentObject() const + { + return mGlobal; + } + + JSObject* + WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + + static bool PrefEnabled(JSContext* aCx, JSObject* aObj); + + // WebIDL interface methods. + + already_AddRefed + Register(const nsAString& aName, ErrorResult& aRv); + + already_AddRefed + GetTags(ErrorResult& aRv); + +private: + BackgroundSync(nsIGlobalObject* aGlobal, + const mozilla::ipc::PrincipalInfo& aPrincipalInfo); + + ~BackgroundSync(); + + nsCOMPtr mGlobal; + + nsAutoPtr mPrincipalInfo; +}; + +} // namespace backgroundsync +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_BackgroundSync_h diff --git a/dom/backgroundsync/moz.build b/dom/backgroundsync/moz.build new file mode 100644 --- /dev/null +++ b/dom/backgroundsync/moz.build @@ -0,0 +1,20 @@ +# 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/. + +EXPORTS.mozilla.dom.backgroundsync += [ + 'BackgroundSync.h' +] + +UNIFIED_SOURCES += [ + 'BackgroundSync.cpp' +] + +LOCAL_INCLUDES += [ + '/dom/workers' +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -89,16 +89,21 @@ DOMInterfaces = { 'AudioNode' : { 'concrete': False, 'binaryNames': { 'channelCountMode': 'channelCountModeValue', 'channelInterpretation': 'channelInterpretationValue', }, }, +'BackgroundSync': { + 'nativeType': 'mozilla::dom::backgroundsync::BackgroundSync', + 'headerFile': 'mozilla/dom/backgroundsync/BackgroundSync.h', +}, + 'BarProp': { 'headerFile': 'mozilla/dom/BarProps.h', }, 'Blob': { 'headerFile': 'mozilla/dom/File.h', }, diff --git a/dom/moz.build b/dom/moz.build --- a/dom/moz.build +++ b/dom/moz.build @@ -37,16 +37,17 @@ interfaces = [ DIRS += ['interfaces/' + i for i in interfaces] DIRS += [ 'animation', 'apps', 'base', 'bluetooth', 'archivereader', + 'backgroundsync', 'bindings', 'battery', 'browser-element', 'cache', 'canvas', 'cellbroadcast', 'contacts', 'crypto', diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -159,16 +159,18 @@ var interfaceNamesInGlobalScope = "AudioParam", // IMPORTANT: Do not change this list without review from a DOM peer! "AudioProcessingEvent", // IMPORTANT: Do not change this list without review from a DOM peer! "AudioStreamTrack", // IMPORTANT: Do not change this list without review from a DOM peer! {name: "AVInputPort", b2g: true, permission: ["inputport"]}, // IMPORTANT: Do not change this list without review from a DOM peer! + {name: "BackgroundSync", b2g: true}, +// IMPORTANT: Do not change this list without review from a DOM peer! "BarProp", // IMPORTANT: Do not change this list without review from a DOM peer! "BatteryManager", // IMPORTANT: Do not change this list without review from a DOM peer! {name: "BeforeAfterKeyboardEvent", b2g: true, permission: ["embed-apps", "before-after-keyboard-event"]}, // IMPORTANT: Do not change this list without review from a DOM peer! "BeforeUnloadEvent", diff --git a/dom/webidl/BackgroundSync.webidl b/dom/webidl/BackgroundSync.webidl new file mode 100644 --- /dev/null +++ b/dom/webidl/BackgroundSync.webidl @@ -0,0 +1,17 @@ +/* -*- Mode: IDL; tab-width: 2; 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/. +* +* The origin of this IDL file is +* https://wicg.github.io/BackgroundSync/spec/ +*/ + +[Exposed=(Window,Worker), + Func="mozilla::dom::backgroundsync::BackgroundSync::PrefEnabled"] +interface BackgroundSync { + [Throws] + Promise register(DOMString tag); + [Throws] + Promise> getTags(); +}; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -44,16 +44,17 @@ WEBIDL_FILES = [ 'AudioNode.webidl', 'AudioParam.webidl', 'AudioProcessingEvent.webidl', 'AudioStreamTrack.webidl', 'AudioTrack.webidl', 'AudioTrackList.webidl', 'AutocompleteInfo.webidl', 'AVInputPort.webidl', + 'BackgroundSync.webidl', 'BarProp.webidl', 'BaseKeyframeTypes.webidl', 'BatteryManager.webidl', 'BeforeAfterKeyboardEvent.webidl', 'BeforeUnloadEvent.webidl', 'BiquadFilterNode.webidl', 'Blob.webidl', 'BoxObject.webidl', diff --git a/dom/workers/WorkerPrefs.h b/dom/workers/WorkerPrefs.h --- a/dom/workers/WorkerPrefs.h +++ b/dom/workers/WorkerPrefs.h @@ -29,16 +29,17 @@ WORKER_SIMPLE_PREF("dom.caches.enabled", WORKER_SIMPLE_PREF("dom.caches.testing.enabled", DOMCachesTestingEnabled, DOM_CACHES_TESTING) WORKER_SIMPLE_PREF("dom.performance.enable_user_timing_logging", PerformanceLoggingEnabled, PERFORMANCE_LOGGING_ENABLED) WORKER_SIMPLE_PREF("dom.webnotifications.enabled", DOMWorkerNotificationEnabled, DOM_WORKERNOTIFICATION) WORKER_SIMPLE_PREF("dom.webnotifications.serviceworker.enabled", DOMServiceWorkerNotificationEnabled, DOM_SERVICEWORKERNOTIFICATION) WORKER_SIMPLE_PREF("dom.serviceWorkers.enabled", ServiceWorkersEnabled, SERVICEWORKERS_ENABLED) WORKER_SIMPLE_PREF("dom.serviceWorkers.testing.enabled", ServiceWorkersTestingEnabled, SERVICEWORKERS_TESTING_ENABLED) WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, OPEN_WINDOW_ENABLED) WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED) +WORKER_SIMPLE_PREF("dom.background.sync.enabled", BackgroundSyncEnabled, BACKGROUND_SYNC_ENABLED) WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED) WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED) WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK) WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged) WORKER_PREF("intl.accept_languages", PrefLanguagesChanged) WORKER_PREF("general.appname.override", AppNameOverrideChanged) WORKER_PREF("general.appversion.override", AppVersionOverrideChanged) WORKER_PREF("general.platform.override", PlatformOverrideChanged)