summaryrefslogtreecommitdiffstats
path: root/toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp')
-rw-r--r--toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp161
1 files changed, 161 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;