1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/diskspacewatcher/DiskSpaceWatcher.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,163 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "DiskSpaceWatcher.h" 1.9 +#include "nsIObserverService.h" 1.10 +#include "nsXULAppAPI.h" 1.11 +#include "mozilla/Hal.h" 1.12 +#include "mozilla/ModuleUtils.h" 1.13 +#include "mozilla/Preferences.h" 1.14 +#include "mozilla/ClearOnShutdown.h" 1.15 +#include "mozilla/Services.h" 1.16 + 1.17 +#define NS_DISKSPACEWATCHER_CID \ 1.18 + { 0xab218518, 0xf197, 0x4fb4, { 0x8b, 0x0f, 0x8b, 0xb3, 0x4d, 0xf2, 0x4b, 0xf4 } } 1.19 + 1.20 +using namespace mozilla; 1.21 + 1.22 +StaticRefPtr<DiskSpaceWatcher> gDiskSpaceWatcher; 1.23 + 1.24 +NS_IMPL_ISUPPORTS(DiskSpaceWatcher, nsIDiskSpaceWatcher, nsIObserver) 1.25 + 1.26 +uint64_t DiskSpaceWatcher::sFreeSpace = 0; 1.27 +bool DiskSpaceWatcher::sIsDiskFull = false; 1.28 + 1.29 +DiskSpaceWatcher::DiskSpaceWatcher() 1.30 +{ 1.31 + MOZ_ASSERT(NS_IsMainThread()); 1.32 + MOZ_ASSERT(!gDiskSpaceWatcher); 1.33 +} 1.34 + 1.35 +DiskSpaceWatcher::~DiskSpaceWatcher() 1.36 +{ 1.37 + MOZ_ASSERT(!gDiskSpaceWatcher); 1.38 +} 1.39 + 1.40 +already_AddRefed<DiskSpaceWatcher> 1.41 +DiskSpaceWatcher::FactoryCreate() 1.42 +{ 1.43 + if (XRE_GetProcessType() != GeckoProcessType_Default) { 1.44 + return nullptr; 1.45 + } 1.46 + 1.47 + MOZ_ASSERT(NS_IsMainThread()); 1.48 + 1.49 + if (!Preferences::GetBool("disk_space_watcher.enabled", false)) { 1.50 + return nullptr; 1.51 + } 1.52 + 1.53 + if (!gDiskSpaceWatcher) { 1.54 + gDiskSpaceWatcher = new DiskSpaceWatcher(); 1.55 + ClearOnShutdown(&gDiskSpaceWatcher); 1.56 + } 1.57 + 1.58 + nsRefPtr<DiskSpaceWatcher> service = gDiskSpaceWatcher.get(); 1.59 + return service.forget(); 1.60 +} 1.61 + 1.62 +NS_IMETHODIMP 1.63 +DiskSpaceWatcher::Observe(nsISupports* aSubject, const char* aTopic, 1.64 + const char16_t* aData) 1.65 +{ 1.66 + MOZ_ASSERT(NS_IsMainThread()); 1.67 + 1.68 + if (!strcmp(aTopic, "profile-after-change")) { 1.69 + nsCOMPtr<nsIObserverService> observerService = 1.70 + mozilla::services::GetObserverService(); 1.71 + observerService->AddObserver(this, "profile-before-change", false); 1.72 + mozilla::hal::StartDiskSpaceWatcher(); 1.73 + return NS_OK; 1.74 + } 1.75 + 1.76 + if (!strcmp(aTopic, "profile-before-change")) { 1.77 + nsCOMPtr<nsIObserverService> observerService = 1.78 + mozilla::services::GetObserverService(); 1.79 + observerService->RemoveObserver(this, "profile-before-change"); 1.80 + mozilla::hal::StopDiskSpaceWatcher(); 1.81 + return NS_OK; 1.82 + } 1.83 + 1.84 + MOZ_ASSERT(false, "DiskSpaceWatcher got unexpected topic!"); 1.85 + return NS_ERROR_UNEXPECTED; 1.86 +} 1.87 + 1.88 +/* readonly attribute bool isDiskFull; */ 1.89 +NS_IMETHODIMP DiskSpaceWatcher::GetIsDiskFull(bool* aIsDiskFull) 1.90 +{ 1.91 + *aIsDiskFull = sIsDiskFull; 1.92 + return NS_OK; 1.93 +} 1.94 + 1.95 +// GetFreeSpace is a macro on windows, and that messes up with the c++ 1.96 +// compiler. 1.97 +#ifdef XP_WIN 1.98 +#undef GetFreeSpace 1.99 +#endif 1.100 +/* readonly attribute long freeSpace; */ 1.101 +NS_IMETHODIMP DiskSpaceWatcher::GetFreeSpace(uint64_t* aFreeSpace) 1.102 +{ 1.103 + *aFreeSpace = sFreeSpace; 1.104 + return NS_OK; 1.105 +} 1.106 + 1.107 +// static 1.108 +void DiskSpaceWatcher::UpdateState(bool aIsDiskFull, uint64_t aFreeSpace) 1.109 +{ 1.110 + MOZ_ASSERT(NS_IsMainThread()); 1.111 + if (!gDiskSpaceWatcher) { 1.112 + return; 1.113 + } 1.114 + 1.115 + nsCOMPtr<nsIObserverService> observerService = 1.116 + mozilla::services::GetObserverService(); 1.117 + 1.118 + sIsDiskFull = aIsDiskFull; 1.119 + sFreeSpace = aFreeSpace; 1.120 + 1.121 + if (!observerService) { 1.122 + return; 1.123 + } 1.124 + 1.125 + const char16_t stateFull[] = { 'f', 'u', 'l', 'l', 0 }; 1.126 + const char16_t stateFree[] = { 'f', 'r', 'e', 'e', 0 }; 1.127 + 1.128 + nsCOMPtr<nsISupports> subject; 1.129 + CallQueryInterface(gDiskSpaceWatcher.get(), getter_AddRefs(subject)); 1.130 + MOZ_ASSERT(subject); 1.131 + observerService->NotifyObservers(subject, 1.132 + DISKSPACEWATCHER_OBSERVER_TOPIC, 1.133 + sIsDiskFull ? stateFull : stateFree); 1.134 + return; 1.135 +} 1.136 + 1.137 +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DiskSpaceWatcher, 1.138 + DiskSpaceWatcher::FactoryCreate) 1.139 + 1.140 +NS_DEFINE_NAMED_CID(NS_DISKSPACEWATCHER_CID); 1.141 + 1.142 +static const mozilla::Module::CIDEntry kDiskSpaceWatcherCIDs[] = { 1.143 + { &kNS_DISKSPACEWATCHER_CID, false, nullptr, DiskSpaceWatcherConstructor }, 1.144 + { nullptr } 1.145 +}; 1.146 + 1.147 +static const mozilla::Module::ContractIDEntry kDiskSpaceWatcherContracts[] = { 1.148 + { "@mozilla.org/toolkit/disk-space-watcher;1", &kNS_DISKSPACEWATCHER_CID }, 1.149 + { nullptr } 1.150 +}; 1.151 + 1.152 +static const mozilla::Module::CategoryEntry kDiskSpaceWatcherCategories[] = { 1.153 +#ifdef MOZ_WIDGET_GONK 1.154 + { "profile-after-change", "Disk Space Watcher Service", DISKSPACEWATCHER_CONTRACTID }, 1.155 +#endif 1.156 + { nullptr } 1.157 +}; 1.158 + 1.159 +static const mozilla::Module kDiskSpaceWatcherModule = { 1.160 + mozilla::Module::kVersion, 1.161 + kDiskSpaceWatcherCIDs, 1.162 + kDiskSpaceWatcherContracts, 1.163 + kDiskSpaceWatcherCategories 1.164 +}; 1.165 + 1.166 +NSMODULE_DEFN(DiskSpaceWatcherModule) = &kDiskSpaceWatcherModule;