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