Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include "DiskSpaceWatcher.h" |
michael@0 | 6 | #include "nsIObserverService.h" |
michael@0 | 7 | #include "nsXULAppAPI.h" |
michael@0 | 8 | #include "mozilla/Hal.h" |
michael@0 | 9 | #include "mozilla/ModuleUtils.h" |
michael@0 | 10 | #include "mozilla/Preferences.h" |
michael@0 | 11 | #include "mozilla/ClearOnShutdown.h" |
michael@0 | 12 | #include "mozilla/Services.h" |
michael@0 | 13 | |
michael@0 | 14 | #define NS_DISKSPACEWATCHER_CID \ |
michael@0 | 15 | { 0xab218518, 0xf197, 0x4fb4, { 0x8b, 0x0f, 0x8b, 0xb3, 0x4d, 0xf2, 0x4b, 0xf4 } } |
michael@0 | 16 | |
michael@0 | 17 | using namespace mozilla; |
michael@0 | 18 | |
michael@0 | 19 | StaticRefPtr<DiskSpaceWatcher> gDiskSpaceWatcher; |
michael@0 | 20 | |
michael@0 | 21 | NS_IMPL_ISUPPORTS(DiskSpaceWatcher, nsIDiskSpaceWatcher, nsIObserver) |
michael@0 | 22 | |
michael@0 | 23 | uint64_t DiskSpaceWatcher::sFreeSpace = 0; |
michael@0 | 24 | bool DiskSpaceWatcher::sIsDiskFull = false; |
michael@0 | 25 | |
michael@0 | 26 | DiskSpaceWatcher::DiskSpaceWatcher() |
michael@0 | 27 | { |
michael@0 | 28 | MOZ_ASSERT(NS_IsMainThread()); |
michael@0 | 29 | MOZ_ASSERT(!gDiskSpaceWatcher); |
michael@0 | 30 | } |
michael@0 | 31 | |
michael@0 | 32 | DiskSpaceWatcher::~DiskSpaceWatcher() |
michael@0 | 33 | { |
michael@0 | 34 | MOZ_ASSERT(!gDiskSpaceWatcher); |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | already_AddRefed<DiskSpaceWatcher> |
michael@0 | 38 | DiskSpaceWatcher::FactoryCreate() |
michael@0 | 39 | { |
michael@0 | 40 | if (XRE_GetProcessType() != GeckoProcessType_Default) { |
michael@0 | 41 | return nullptr; |
michael@0 | 42 | } |
michael@0 | 43 | |
michael@0 | 44 | MOZ_ASSERT(NS_IsMainThread()); |
michael@0 | 45 | |
michael@0 | 46 | if (!Preferences::GetBool("disk_space_watcher.enabled", false)) { |
michael@0 | 47 | return nullptr; |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | if (!gDiskSpaceWatcher) { |
michael@0 | 51 | gDiskSpaceWatcher = new DiskSpaceWatcher(); |
michael@0 | 52 | ClearOnShutdown(&gDiskSpaceWatcher); |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | nsRefPtr<DiskSpaceWatcher> service = gDiskSpaceWatcher.get(); |
michael@0 | 56 | return service.forget(); |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | NS_IMETHODIMP |
michael@0 | 60 | DiskSpaceWatcher::Observe(nsISupports* aSubject, const char* aTopic, |
michael@0 | 61 | const char16_t* aData) |
michael@0 | 62 | { |
michael@0 | 63 | MOZ_ASSERT(NS_IsMainThread()); |
michael@0 | 64 | |
michael@0 | 65 | if (!strcmp(aTopic, "profile-after-change")) { |
michael@0 | 66 | nsCOMPtr<nsIObserverService> observerService = |
michael@0 | 67 | mozilla::services::GetObserverService(); |
michael@0 | 68 | observerService->AddObserver(this, "profile-before-change", false); |
michael@0 | 69 | mozilla::hal::StartDiskSpaceWatcher(); |
michael@0 | 70 | return NS_OK; |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | if (!strcmp(aTopic, "profile-before-change")) { |
michael@0 | 74 | nsCOMPtr<nsIObserverService> observerService = |
michael@0 | 75 | mozilla::services::GetObserverService(); |
michael@0 | 76 | observerService->RemoveObserver(this, "profile-before-change"); |
michael@0 | 77 | mozilla::hal::StopDiskSpaceWatcher(); |
michael@0 | 78 | return NS_OK; |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | MOZ_ASSERT(false, "DiskSpaceWatcher got unexpected topic!"); |
michael@0 | 82 | return NS_ERROR_UNEXPECTED; |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | /* readonly attribute bool isDiskFull; */ |
michael@0 | 86 | NS_IMETHODIMP DiskSpaceWatcher::GetIsDiskFull(bool* aIsDiskFull) |
michael@0 | 87 | { |
michael@0 | 88 | *aIsDiskFull = sIsDiskFull; |
michael@0 | 89 | return NS_OK; |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | // GetFreeSpace is a macro on windows, and that messes up with the c++ |
michael@0 | 93 | // compiler. |
michael@0 | 94 | #ifdef XP_WIN |
michael@0 | 95 | #undef GetFreeSpace |
michael@0 | 96 | #endif |
michael@0 | 97 | /* readonly attribute long freeSpace; */ |
michael@0 | 98 | NS_IMETHODIMP DiskSpaceWatcher::GetFreeSpace(uint64_t* aFreeSpace) |
michael@0 | 99 | { |
michael@0 | 100 | *aFreeSpace = sFreeSpace; |
michael@0 | 101 | return NS_OK; |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | // static |
michael@0 | 105 | void DiskSpaceWatcher::UpdateState(bool aIsDiskFull, uint64_t aFreeSpace) |
michael@0 | 106 | { |
michael@0 | 107 | MOZ_ASSERT(NS_IsMainThread()); |
michael@0 | 108 | if (!gDiskSpaceWatcher) { |
michael@0 | 109 | return; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | nsCOMPtr<nsIObserverService> observerService = |
michael@0 | 113 | mozilla::services::GetObserverService(); |
michael@0 | 114 | |
michael@0 | 115 | sIsDiskFull = aIsDiskFull; |
michael@0 | 116 | sFreeSpace = aFreeSpace; |
michael@0 | 117 | |
michael@0 | 118 | if (!observerService) { |
michael@0 | 119 | return; |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | const char16_t stateFull[] = { 'f', 'u', 'l', 'l', 0 }; |
michael@0 | 123 | const char16_t stateFree[] = { 'f', 'r', 'e', 'e', 0 }; |
michael@0 | 124 | |
michael@0 | 125 | nsCOMPtr<nsISupports> subject; |
michael@0 | 126 | CallQueryInterface(gDiskSpaceWatcher.get(), getter_AddRefs(subject)); |
michael@0 | 127 | MOZ_ASSERT(subject); |
michael@0 | 128 | observerService->NotifyObservers(subject, |
michael@0 | 129 | DISKSPACEWATCHER_OBSERVER_TOPIC, |
michael@0 | 130 | sIsDiskFull ? stateFull : stateFree); |
michael@0 | 131 | return; |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DiskSpaceWatcher, |
michael@0 | 135 | DiskSpaceWatcher::FactoryCreate) |
michael@0 | 136 | |
michael@0 | 137 | NS_DEFINE_NAMED_CID(NS_DISKSPACEWATCHER_CID); |
michael@0 | 138 | |
michael@0 | 139 | static const mozilla::Module::CIDEntry kDiskSpaceWatcherCIDs[] = { |
michael@0 | 140 | { &kNS_DISKSPACEWATCHER_CID, false, nullptr, DiskSpaceWatcherConstructor }, |
michael@0 | 141 | { nullptr } |
michael@0 | 142 | }; |
michael@0 | 143 | |
michael@0 | 144 | static const mozilla::Module::ContractIDEntry kDiskSpaceWatcherContracts[] = { |
michael@0 | 145 | { "@mozilla.org/toolkit/disk-space-watcher;1", &kNS_DISKSPACEWATCHER_CID }, |
michael@0 | 146 | { nullptr } |
michael@0 | 147 | }; |
michael@0 | 148 | |
michael@0 | 149 | static const mozilla::Module::CategoryEntry kDiskSpaceWatcherCategories[] = { |
michael@0 | 150 | #ifdef MOZ_WIDGET_GONK |
michael@0 | 151 | { "profile-after-change", "Disk Space Watcher Service", DISKSPACEWATCHER_CONTRACTID }, |
michael@0 | 152 | #endif |
michael@0 | 153 | { nullptr } |
michael@0 | 154 | }; |
michael@0 | 155 | |
michael@0 | 156 | static const mozilla::Module kDiskSpaceWatcherModule = { |
michael@0 | 157 | mozilla::Module::kVersion, |
michael@0 | 158 | kDiskSpaceWatcherCIDs, |
michael@0 | 159 | kDiskSpaceWatcherContracts, |
michael@0 | 160 | kDiskSpaceWatcherCategories |
michael@0 | 161 | }; |
michael@0 | 162 | |
michael@0 | 163 | NSMODULE_DEFN(DiskSpaceWatcherModule) = &kDiskSpaceWatcherModule; |