☠☠ backed out by ca0c739344f2 ☠ ☠ | |
author | Andrea Marchesini <amarchesini@mozilla.com> |
Mon, 08 Jan 2018 08:31:34 +0100 | |
changeset 449957 | f4955cf6447f23ced615c6b8855b158e987ae4f8 |
parent 449956 | cb4fd975b8bb668aa5b877386b8cf02f62561107 |
child 449958 | 609093736110bbd6b341cbb00f91c1f5f5553ee4 |
push id | 8527 |
push user | Callek@gmail.com |
push date | Thu, 11 Jan 2018 21:05:50 +0000 |
treeherder | mozilla-beta@95342d212a7a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | asuth |
bugs | 1252998 |
milestone | 59.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/interfaces/storage/moz.build +++ b/dom/interfaces/storage/moz.build @@ -5,11 +5,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. with Files("**"): BUG_COMPONENT = ("Core", "DOM") XPIDL_SOURCES += [ 'nsIDOMStorage.idl', 'nsIDOMStorageManager.idl', + 'nsIStorageActivityService.idl', ] XPIDL_MODULE = 'dom_storage'
new file mode 100644 --- /dev/null +++ b/dom/interfaces/storage/nsIStorageActivityService.idl @@ -0,0 +1,25 @@ +/* -*- 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/. */ + +#include "domstubs.idl" + +/** + * nsIStorageActivityService is a service that can be used to know which + * origins have been active in a time range. This information can be used to + * implement "Clear Recent History" or similar features. + * + * If you are implementing a new Storage component, you should use + * QuotaManager. But if you don't do it, remember to call + * StorageActivityService methods in order to inform this service about + * 'writing' operations executed by origins. + */ +[scriptable, builtinclass, uuid(fd1310ba-d1be-4327-988e-92b39fcff6f4)] +interface nsIStorageActivityService : nsISupports +{ +}; + +%{ C++ +#define STORAGE_ACTIVITY_SERVICE_CONTRACTID "@mozilla.org/storage/activity-service;1" +%}
new file mode 100644 --- /dev/null +++ b/dom/storage/StorageActivityService.cpp @@ -0,0 +1,209 @@ +/* -*- 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 "StorageActivityService.h" + +#include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/StaticPtr.h" +#include "nsXPCOM.h" + +// This const is used to know when origin activities should be purged because +// too old. This value should be in sync with what the UI needs. +#define TIME_MAX_SECS 86400 /* 24 hours */ + +namespace mozilla { +namespace dom { + +static StaticRefPtr<StorageActivityService> gStorageActivityService; +static bool gStorageActivityShutdown = false; + +/* static */ void +StorageActivityService::SendActivity(nsIPrincipal* aPrincipal) +{ + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr<StorageActivityService> service = GetOrCreate(); + if (NS_WARN_IF(!service)) { + return; + } + + service->SendActivityInternal(aPrincipal); +} + +/* static */ void +StorageActivityService::SendActivity(const mozilla::ipc::PrincipalInfo& aPrincipalInfo) +{ + RefPtr<Runnable> r = NS_NewRunnableFunction( + "StorageActivityService::SendActivity", + [aPrincipalInfo] () { + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr<nsIPrincipal> principal = + mozilla::ipc::PrincipalInfoToPrincipal(aPrincipalInfo); + + StorageActivityService::SendActivity(principal); + }); + + SystemGroup::Dispatch(TaskCategory::Other, r.forget()); +} + +/* static */ already_AddRefed<StorageActivityService> +StorageActivityService::GetOrCreate() +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!gStorageActivityService && !gStorageActivityShutdown) { + RefPtr<StorageActivityService> service = new StorageActivityService(); + + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (NS_WARN_IF(!obs)) { + return nullptr; + } + + nsresult rv = obs->AddObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + gStorageActivityService = service; + } + + RefPtr<StorageActivityService> service = gStorageActivityService; + return service.forget(); +} + +StorageActivityService::StorageActivityService() +{ + MOZ_ASSERT(NS_IsMainThread()); +} + +StorageActivityService::~StorageActivityService() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mTimer); +} + +void +StorageActivityService::SendActivityInternal(nsIPrincipal* aPrincipal) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aPrincipal); + + if (!XRE_IsParentProcess()) { + SendActivityToParent(aPrincipal); + return; + } + + nsAutoCString origin; + nsresult rv = aPrincipal->GetOrigin(origin); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + mActivities.Put(origin, TimeStamp::NowLoRes()); + + MaybeStartTimer(); +} + +void +StorageActivityService::SendActivityToParent(nsIPrincipal* aPrincipal) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!XRE_IsParentProcess()); + + PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread(); + if (NS_WARN_IF(!actor)) { + return; + } + + mozilla::ipc::PrincipalInfo principalInfo; + nsresult rv = + mozilla::ipc::PrincipalToPrincipalInfo(aPrincipal, &principalInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + actor->SendStorageActivity(principalInfo); +} + +NS_IMETHODIMP +StorageActivityService::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)); + + MaybeStopTimer(); + + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); + } + + gStorageActivityShutdown = true; + gStorageActivityService = nullptr; + return NS_OK; +} + +void +StorageActivityService::MaybeStartTimer() +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!mTimer) { + mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); + mTimer->InitWithCallback(this, + 1000 * 5 * 60 /* any 5 minutes */, + nsITimer::TYPE_REPEATING_SLACK); + } +} + +void +StorageActivityService::MaybeStopTimer() +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (mTimer) { + mTimer->Cancel(); + mTimer = nullptr; + } +} + +NS_IMETHODIMP +StorageActivityService::Notify(nsITimer* aTimer) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mTimer == aTimer); + + TimeStamp now = TimeStamp::NowLoRes(); + + for (auto iter = mActivities.Iter(); !iter.Done(); iter.Next()) { + if ((now - iter.UserData()).ToSeconds() > TIME_MAX_SECS) { + iter.Remove(); + } + } + + // If no activities, let's stop the timer. + if (mActivities.Count() == 0) { + MaybeStopTimer(); + } + + return NS_OK; +} + +NS_INTERFACE_MAP_BEGIN(StorageActivityService) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStorageActivityService) + NS_INTERFACE_MAP_ENTRY(nsIStorageActivityService) + NS_INTERFACE_MAP_ENTRY(nsIObserver) + NS_INTERFACE_MAP_ENTRY(nsITimerCallback) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +NS_INTERFACE_MAP_END + +NS_IMPL_ADDREF(StorageActivityService) +NS_IMPL_RELEASE(StorageActivityService) + +} // dom namespace +} // mozilla namespace
new file mode 100644 --- /dev/null +++ b/dom/storage/StorageActivityService.h @@ -0,0 +1,71 @@ +/* -*- 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_StorageActivityService_h +#define mozilla_dom_StorageActivityService_h + +#include "nsDataHashtable.h" +#include "nsIStorageActivityService.h" +#include "nsITimer.h" +#include "nsWeakReference.h" + +namespace mozilla { + +namespace ipc { +class PrincipalInfo; +} // ipc + +namespace dom { + +class StorageActivityService final : public nsIStorageActivityService + , public nsIObserver + , public nsITimerCallback + , public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISTORAGEACTIVITYSERVICE + NS_DECL_NSIOBSERVER + NS_DECL_NSITIMERCALLBACK + + // Main-thread only. + static void + SendActivity(nsIPrincipal* aPrincipal); + + // Thread-safe. + static void + SendActivity(const mozilla::ipc::PrincipalInfo& aPrincipalInfo); + + // Used by XPCOM. Don't use it, use SendActivity() instead. + static already_AddRefed<StorageActivityService> + GetOrCreate(); + +private: + StorageActivityService(); + ~StorageActivityService(); + + void + SendActivityInternal(nsIPrincipal* aPrincipal); + + void + SendActivityToParent(nsIPrincipal* aPrincipal); + + void + MaybeStartTimer(); + + void + MaybeStopTimer(); + + // Activities grouped by origin (+OriginAttributes). + nsDataHashtable<nsCStringHashKey, TimeStamp> mActivities; + + nsCOMPtr<nsITimer> mTimer; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_StorageActivityService_h
--- a/dom/storage/moz.build +++ b/dom/storage/moz.build @@ -7,29 +7,31 @@ with Files("**"): BUG_COMPONENT = ("Core", "DOM") EXPORTS.mozilla.dom += [ 'LocalStorage.h', 'LocalStorageManager.h', 'SessionStorageManager.h', 'Storage.h', + 'StorageActivityService.h', 'StorageIPC.h', 'StorageNotifierService.h', 'StorageUtils.h', ] UNIFIED_SOURCES += [ 'LocalStorage.cpp', 'LocalStorageCache.cpp', 'LocalStorageManager.cpp', 'SessionStorage.cpp', 'SessionStorageCache.cpp', 'SessionStorageManager.cpp', 'Storage.cpp', + 'StorageActivityService.cpp', 'StorageDBThread.cpp', 'StorageDBUpdater.cpp', 'StorageIPC.cpp', 'StorageNotifierService.cpp', 'StorageObserver.cpp', 'StorageUtils.cpp', ]
--- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -19,16 +19,17 @@ #include "mozilla/dom/FileSystemBase.h" #include "mozilla/dom/FileSystemRequestParent.h" #include "mozilla/dom/GamepadEventChannelParent.h" #include "mozilla/dom/GamepadTestChannelParent.h" #include "mozilla/dom/PGamepadEventChannelParent.h" #include "mozilla/dom/PGamepadTestChannelParent.h" #include "mozilla/dom/MessagePortParent.h" #include "mozilla/dom/ServiceWorkerRegistrar.h" +#include "mozilla/dom/StorageActivityService.h" #include "mozilla/dom/asmjscache/AsmJSCache.h" #include "mozilla/dom/cache/ActorUtils.h" #include "mozilla/dom/indexedDB/ActorsParent.h" #include "mozilla/dom/ipc/IPCBlobInputStreamParent.h" #include "mozilla/dom/ipc/PendingIPCBlobParent.h" #include "mozilla/dom/ipc/TemporaryIPCBlobParent.h" #include "mozilla/dom/quota/ActorsParent.h" #include "mozilla/dom/StorageIPC.h" @@ -982,16 +983,23 @@ BackgroundParentImpl::DeallocPClientMana mozilla::ipc::IPCResult BackgroundParentImpl::RecvPClientManagerConstructor(mozilla::dom::PClientManagerParent* aActor) { mozilla::dom::InitClientManagerParent(aActor); return IPC_OK(); } +IPCResult +BackgroundParentImpl::RecvStorageActivity(const PrincipalInfo& aPrincipalInfo) +{ + dom::StorageActivityService::SendActivity(aPrincipalInfo); + return IPC_OK(); +} + } // namespace ipc } // namespace mozilla void TestParent::ActorDestroy(ActorDestroyReason aWhy) { mozilla::ipc::AssertIsInMainProcess(); AssertIsOnBackgroundThread();
--- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -266,14 +266,17 @@ protected: virtual PClientManagerParent* AllocPClientManagerParent() override; virtual bool DeallocPClientManagerParent(PClientManagerParent* aActor) override; virtual mozilla::ipc::IPCResult RecvPClientManagerConstructor(PClientManagerParent* aActor) override; + + virtual mozilla::ipc::IPCResult + RecvStorageActivity(const PrincipalInfo& aPrincipalInfo) override; }; } // namespace ipc } // namespace mozilla #endif // mozilla_ipc_backgroundparentimpl_h__
--- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -135,16 +135,20 @@ parent: async PHttpBackgroundChannel(uint64_t channelId); async PWebAuthnTransaction(); async PTemporaryIPCBlob(); async PClientManager(); + // This method is used to propagate storage activities from the child actor + // to the parent actor. See StorageActivityService. + async StorageActivity(PrincipalInfo principalInfo); + child: async PCache(); async PCacheStreamControl(); async PParentToChildStream(); async PPendingIPCBlob(IPCBlob blob);
--- a/layout/build/nsLayoutCID.h +++ b/layout/build/nsLayoutCID.h @@ -74,12 +74,16 @@ // {5a75c25a-5e7e-4d90-8f7c-07eb15cc0aa8} #define QUOTAMANAGER_SERVICE_CID \ { 0x5a75c25a, 0x5e7e, 0x4d90, { 0x8f, 0x7c, 0x07, 0xeb, 0x15, 0xcc, 0x0a, 0xa8 } } // {c74bde32-bcc7-4840-8430-c733351b212a} #define SERVICEWORKERMANAGER_CID \ { 0xc74bde32, 0xbcc7, 0x4840, { 0x84, 0x30, 0xc7, 0x33, 0x35, 0x1b, 0x21, 0x2a } } +// {69da374a-fda3-4a93-9fbc-d9304f66a7fe} +#define STORAGEACTIVITYSERVICE_CID \ +{ 0x69da374a, 0xfda3, 0x4a93, { 0x9f, 0xbc, 0xd9, 0x30, 0x4f, 0x66, 0xa7, 0xfe } } + #define NOTIFICATIONTELEMETRYSERVICE_CID \ { 0x5995b782, 0x6a0e, 0x4066, { 0xaa, 0xc5, 0x27, 0x6f, 0x0a, 0x9a, 0xd8, 0xcf } } #endif /* nsLayoutCID_h__ */
--- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -78,16 +78,17 @@ #include "nsZipArchive.h" #include "mozilla/Attributes.h" #include "mozilla/dom/DOMException.h" #include "mozilla/dom/DOMRequest.h" #include "mozilla/dom/LocalStorageManager.h" #include "mozilla/dom/network/UDPSocketChild.h" #include "mozilla/dom/quota/QuotaManagerService.h" #include "mozilla/dom/SessionStorageManager.h" +#include "mozilla/dom/StorageActivityService.h" #include "mozilla/dom/workers/ServiceWorkerManager.h" #include "mozilla/dom/workers/WorkerDebuggerManager.h" #include "mozilla/dom/Notification.h" #include "mozilla/OSFileConstants.h" #include "mozilla/Services.h" #ifdef MOZ_WEBSPEECH_TEST_BACKEND #include "mozilla/dom/FakeSpeechRecognitionService.h" @@ -247,16 +248,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(SessionSt NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DOMRequestService, DOMRequestService::FactoryCreate) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(QuotaManagerService, QuotaManagerService::FactoryCreate) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ServiceWorkerManager, ServiceWorkerManager::GetInstance) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WorkerDebuggerManager, WorkerDebuggerManager::GetInstance) +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(StorageActivityService, + StorageActivityService::GetOrCreate) #ifdef MOZ_WEBSPEECH NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSynthVoiceRegistry, nsSynthVoiceRegistry::GetInstanceForService) #endif NS_GENERIC_FACTORY_CONSTRUCTOR(AudioChannelAgent) @@ -620,16 +623,17 @@ NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID); NS_DEFINE_NAMED_CID(NS_DOMPARSER_CID); NS_DEFINE_NAMED_CID(NS_DOMSESSIONSTORAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_DOMLOCALSTORAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID); NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID); NS_DEFINE_NAMED_CID(QUOTAMANAGER_SERVICE_CID); NS_DEFINE_NAMED_CID(SERVICEWORKERMANAGER_CID); +NS_DEFINE_NAMED_CID(STORAGEACTIVITYSERVICE_CID); NS_DEFINE_NAMED_CID(NOTIFICATIONTELEMETRYSERVICE_CID); NS_DEFINE_NAMED_CID(PUSHNOTIFIER_CID); NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID); NS_DEFINE_NAMED_CID(NS_AUDIOCHANNELAGENT_CID); NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID); NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID); NS_DEFINE_NAMED_CID(NS_EDITINGCONTROLLER_CID); NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID); @@ -877,16 +881,17 @@ static const mozilla::Module::CIDEntry k { &kNS_DOMPARSER_CID, false, nullptr, DOMParserConstructor }, { &kNS_XPCEXCEPTION_CID, false, nullptr, ExceptionConstructor }, { &kNS_DOMSESSIONSTORAGEMANAGER_CID, false, nullptr, SessionStorageManagerConstructor }, { &kNS_DOMLOCALSTORAGEMANAGER_CID, false, nullptr, LocalStorageManagerConstructor }, { &kNS_TEXTEDITOR_CID, false, nullptr, TextEditorConstructor }, { &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor }, { &kQUOTAMANAGER_SERVICE_CID, false, nullptr, QuotaManagerServiceConstructor }, { &kSERVICEWORKERMANAGER_CID, false, nullptr, ServiceWorkerManagerConstructor }, + { &kSTORAGEACTIVITYSERVICE_CID, false, nullptr, StorageActivityServiceConstructor }, { &kNOTIFICATIONTELEMETRYSERVICE_CID, false, nullptr, NotificationTelemetryServiceConstructor }, { &kPUSHNOTIFIER_CID, false, nullptr, PushNotifierConstructor }, { &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor }, { &kNS_AUDIOCHANNELAGENT_CID, true, nullptr, AudioChannelAgentConstructor }, { &kNS_HTMLEDITOR_CID, false, nullptr, HTMLEditorConstructor }, { &kNS_EDITORCONTROLLER_CID, false, nullptr, EditorControllerConstructor }, { &kNS_EDITINGCONTROLLER_CID, false, nullptr, nsEditingControllerConstructor }, { &kNS_EDITORCOMMANDTABLE_CID, false, nullptr, nsEditorCommandTableConstructor }, @@ -1002,16 +1007,17 @@ static const mozilla::Module::ContractID { "@mozilla.org/dom/localStorage-manager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID }, // Keeping the old ContractID for backward compatibility { "@mozilla.org/dom/storagemanager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID }, { "@mozilla.org/dom/sessionStorage-manager;1", &kNS_DOMSESSIONSTORAGEMANAGER_CID }, { "@mozilla.org/editor/texteditor;1", &kNS_TEXTEDITOR_CID }, { DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID }, { QUOTAMANAGER_SERVICE_CONTRACTID, &kQUOTAMANAGER_SERVICE_CID }, { SERVICEWORKERMANAGER_CONTRACTID, &kSERVICEWORKERMANAGER_CID }, + { STORAGE_ACTIVITY_SERVICE_CONTRACTID, &kSTORAGEACTIVITYSERVICE_CID }, { NOTIFICATIONTELEMETRYSERVICE_CONTRACTID, &kNOTIFICATIONTELEMETRYSERVICE_CID }, { PUSHNOTIFIER_CONTRACTID, &kPUSHNOTIFIER_CID }, { WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID }, { NS_AUDIOCHANNELAGENT_CONTRACTID, &kNS_AUDIOCHANNELAGENT_CID }, { "@mozilla.org/editor/htmleditor;1", &kNS_HTMLEDITOR_CID }, { "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID }, { "@mozilla.org/editor/editingcontroller;1", &kNS_EDITINGCONTROLLER_CID }, { "@mozilla.org/textservices/textservicesdocument;1", &kNS_TEXTSERVICESDOCUMENT_CID },