diff options
Diffstat (limited to 'toolkit/components/diskspacewatcher')
4 files changed, 241 insertions, 0 deletions
diff --git a/toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp b/toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp new file mode 100644 index 000000000..950d3b487 --- /dev/null +++ b/toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp @@ -0,0 +1,161 @@ +/* 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 "DiskSpaceWatcher.h" +#include "nsIObserverService.h" +#include "nsXULAppAPI.h" +#include "mozilla/Hal.h" +#include "mozilla/ModuleUtils.h" +#include "mozilla/Preferences.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Services.h" + +#define NS_DISKSPACEWATCHER_CID \ + { 0xab218518, 0xf197, 0x4fb4, { 0x8b, 0x0f, 0x8b, 0xb3, 0x4d, 0xf2, 0x4b, 0xf4 } } + +using namespace mozilla; + +StaticRefPtr<DiskSpaceWatcher> gDiskSpaceWatcher; + +NS_IMPL_ISUPPORTS(DiskSpaceWatcher, nsIDiskSpaceWatcher, nsIObserver) + +uint64_t DiskSpaceWatcher::sFreeSpace = 0; +bool DiskSpaceWatcher::sIsDiskFull = false; + +DiskSpaceWatcher::DiskSpaceWatcher() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!gDiskSpaceWatcher); +} + +DiskSpaceWatcher::~DiskSpaceWatcher() +{ + MOZ_ASSERT(!gDiskSpaceWatcher); +} + +already_AddRefed<DiskSpaceWatcher> +DiskSpaceWatcher::FactoryCreate() +{ + if (!XRE_IsParentProcess()) { + return nullptr; + } + + MOZ_ASSERT(NS_IsMainThread()); + + if (!Preferences::GetBool("disk_space_watcher.enabled", false)) { + return nullptr; + } + + if (!gDiskSpaceWatcher) { + gDiskSpaceWatcher = new DiskSpaceWatcher(); + ClearOnShutdown(&gDiskSpaceWatcher); + } + + RefPtr<DiskSpaceWatcher> service = gDiskSpaceWatcher.get(); + return service.forget(); +} + +NS_IMETHODIMP +DiskSpaceWatcher::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!strcmp(aTopic, "profile-after-change")) { + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + observerService->AddObserver(this, "profile-before-change", false); + mozilla::hal::StartDiskSpaceWatcher(); + return NS_OK; + } + + if (!strcmp(aTopic, "profile-before-change")) { + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + observerService->RemoveObserver(this, "profile-before-change"); + mozilla::hal::StopDiskSpaceWatcher(); + return NS_OK; + } + + MOZ_ASSERT(false, "DiskSpaceWatcher got unexpected topic!"); + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP DiskSpaceWatcher::GetIsDiskFull(bool* aIsDiskFull) +{ + *aIsDiskFull = sIsDiskFull; + return NS_OK; +} + +// GetFreeSpace is a macro on windows, and that messes up with the c++ +// compiler. +#ifdef XP_WIN +#undef GetFreeSpace +#endif +NS_IMETHODIMP DiskSpaceWatcher::GetFreeSpace(uint64_t* aFreeSpace) +{ + *aFreeSpace = sFreeSpace; + return NS_OK; +} + +// static +void DiskSpaceWatcher::UpdateState(bool aIsDiskFull, uint64_t aFreeSpace) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!gDiskSpaceWatcher) { + return; + } + + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + + sIsDiskFull = aIsDiskFull; + sFreeSpace = aFreeSpace; + + if (!observerService) { + return; + } + + const char16_t stateFull[] = { 'f', 'u', 'l', 'l', 0 }; + const char16_t stateFree[] = { 'f', 'r', 'e', 'e', 0 }; + + nsCOMPtr<nsISupports> subject; + CallQueryInterface(gDiskSpaceWatcher.get(), getter_AddRefs(subject)); + MOZ_ASSERT(subject); + observerService->NotifyObservers(subject, + DISKSPACEWATCHER_OBSERVER_TOPIC, + sIsDiskFull ? stateFull : stateFree); + return; +} + +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DiskSpaceWatcher, + DiskSpaceWatcher::FactoryCreate) + +NS_DEFINE_NAMED_CID(NS_DISKSPACEWATCHER_CID); + +static const mozilla::Module::CIDEntry kDiskSpaceWatcherCIDs[] = { + { &kNS_DISKSPACEWATCHER_CID, false, nullptr, DiskSpaceWatcherConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kDiskSpaceWatcherContracts[] = { + { "@mozilla.org/toolkit/disk-space-watcher;1", &kNS_DISKSPACEWATCHER_CID }, + { nullptr } +}; + +static const mozilla::Module::CategoryEntry kDiskSpaceWatcherCategories[] = { +#ifdef MOZ_WIDGET_GONK + { "profile-after-change", "Disk Space Watcher Service", DISKSPACEWATCHER_CONTRACTID }, +#endif + { nullptr } +}; + +static const mozilla::Module kDiskSpaceWatcherModule = { + mozilla::Module::kVersion, + kDiskSpaceWatcherCIDs, + kDiskSpaceWatcherContracts, + kDiskSpaceWatcherCategories +}; + +NSMODULE_DEFN(DiskSpaceWatcherModule) = &kDiskSpaceWatcherModule; diff --git a/toolkit/components/diskspacewatcher/DiskSpaceWatcher.h b/toolkit/components/diskspacewatcher/DiskSpaceWatcher.h new file mode 100644 index 000000000..6559af3cd --- /dev/null +++ b/toolkit/components/diskspacewatcher/DiskSpaceWatcher.h @@ -0,0 +1,32 @@ +/* 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 __DISKSPACEWATCHER_H__ + +#include "nsIDiskSpaceWatcher.h" +#include "nsIObserver.h" +#include "nsCOMPtr.h" + +class DiskSpaceWatcher final : public nsIDiskSpaceWatcher, + public nsIObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDISKSPACEWATCHER + NS_DECL_NSIOBSERVER + + static already_AddRefed<DiskSpaceWatcher> + FactoryCreate(); + + static void UpdateState(bool aIsDiskFull, uint64_t aFreeSpace); + +private: + DiskSpaceWatcher(); + ~DiskSpaceWatcher(); + + static uint64_t sFreeSpace; + static bool sIsDiskFull; +}; + +#endif // __DISKSPACEWATCHER_H__ diff --git a/toolkit/components/diskspacewatcher/moz.build b/toolkit/components/diskspacewatcher/moz.build new file mode 100644 index 000000000..168af46a6 --- /dev/null +++ b/toolkit/components/diskspacewatcher/moz.build @@ -0,0 +1,23 @@ +# -*- 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/. + +XPIDL_SOURCES += [ + 'nsIDiskSpaceWatcher.idl', +] + +EXPORTS += [ + 'DiskSpaceWatcher.h' +] + +XPIDL_MODULE = 'diskspacewatcher' + +SOURCES = [ + 'DiskSpaceWatcher.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' diff --git a/toolkit/components/diskspacewatcher/nsIDiskSpaceWatcher.idl b/toolkit/components/diskspacewatcher/nsIDiskSpaceWatcher.idl new file mode 100644 index 000000000..a9c60ca9f --- /dev/null +++ b/toolkit/components/diskspacewatcher/nsIDiskSpaceWatcher.idl @@ -0,0 +1,25 @@ +/* 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" + +%{ C++ +#ifdef XP_WIN +#undef GetFreeSpace +#endif +%} + +[scriptable, uuid(3aceba74-2ed5-4e99-8fe4-06e90e2b8ef0)] +interface nsIDiskSpaceWatcher : nsISupports +{ + readonly attribute bool isDiskFull; // True if we are low on disk space. + readonly attribute unsigned long long freeSpace; // The free space currently available. +}; + +%{ C++ +#define DISKSPACEWATCHER_CONTRACTID "@mozilla.org/toolkit/disk-space-watcher;1" + +// The data for this notification will be either 'free' or 'full'. +#define DISKSPACEWATCHER_OBSERVER_TOPIC "disk-space-watcher" +%} |