/src/mozilla-central/netwerk/cache2/CacheObserver.cpp
Line | Count | Source (jump to first uncovered line) |
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 "CacheObserver.h" |
6 | | |
7 | | #include "CacheStorageService.h" |
8 | | #include "CacheFileIOManager.h" |
9 | | #include "LoadContextInfo.h" |
10 | | #include "nsICacheStorage.h" |
11 | | #include "nsIObserverService.h" |
12 | | #include "mozilla/Services.h" |
13 | | #include "mozilla/Preferences.h" |
14 | | #include "mozilla/TimeStamp.h" |
15 | | #include "nsServiceManagerUtils.h" |
16 | | #include "mozilla/net/NeckoCommon.h" |
17 | | #include "prsystem.h" |
18 | | #include <time.h> |
19 | | #include <math.h> |
20 | | |
21 | | namespace mozilla { |
22 | | namespace net { |
23 | | |
24 | | CacheObserver* CacheObserver::sSelf = nullptr; |
25 | | |
26 | | static float const kDefaultHalfLifeHours = 24.0F; // 24 hours |
27 | | float CacheObserver::sHalfLifeHours = kDefaultHalfLifeHours; |
28 | | |
29 | | static bool const kDefaultUseDiskCache = true; |
30 | | bool CacheObserver::sUseDiskCache = kDefaultUseDiskCache; |
31 | | |
32 | | static bool const kDefaultUseMemoryCache = true; |
33 | | bool CacheObserver::sUseMemoryCache = kDefaultUseMemoryCache; |
34 | | |
35 | | static uint32_t const kDefaultMetadataMemoryLimit = 250; // 0.25 MB |
36 | | uint32_t CacheObserver::sMetadataMemoryLimit = kDefaultMetadataMemoryLimit; |
37 | | |
38 | | static int32_t const kDefaultMemoryCacheCapacity = -1; // autodetect |
39 | | int32_t CacheObserver::sMemoryCacheCapacity = kDefaultMemoryCacheCapacity; |
40 | | // Cache of the calculated memory capacity based on the system memory size |
41 | | int32_t CacheObserver::sAutoMemoryCacheCapacity = -1; |
42 | | |
43 | | static uint32_t const kDefaultDiskCacheCapacity = 250 * 1024; // 250 MB |
44 | | Atomic<uint32_t,Relaxed> CacheObserver::sDiskCacheCapacity |
45 | | (kDefaultDiskCacheCapacity); |
46 | | |
47 | | static uint32_t const kDefaultDiskFreeSpaceSoftLimit = 5 * 1024; // 5MB |
48 | | uint32_t CacheObserver::sDiskFreeSpaceSoftLimit = kDefaultDiskFreeSpaceSoftLimit; |
49 | | |
50 | | static uint32_t const kDefaultDiskFreeSpaceHardLimit = 1024; // 1MB |
51 | | uint32_t CacheObserver::sDiskFreeSpaceHardLimit = kDefaultDiskFreeSpaceHardLimit; |
52 | | |
53 | | static bool const kDefaultSmartCacheSizeEnabled = false; |
54 | | bool CacheObserver::sSmartCacheSizeEnabled = kDefaultSmartCacheSizeEnabled; |
55 | | |
56 | | static uint32_t const kDefaultPreloadChunkCount = 4; |
57 | | uint32_t CacheObserver::sPreloadChunkCount = kDefaultPreloadChunkCount; |
58 | | |
59 | | static int32_t const kDefaultMaxMemoryEntrySize = 4 * 1024; // 4 MB |
60 | | int32_t CacheObserver::sMaxMemoryEntrySize = kDefaultMaxMemoryEntrySize; |
61 | | |
62 | | static int32_t const kDefaultMaxDiskEntrySize = 50 * 1024; // 50 MB |
63 | | int32_t CacheObserver::sMaxDiskEntrySize = kDefaultMaxDiskEntrySize; |
64 | | |
65 | | static uint32_t const kDefaultMaxDiskChunksMemoryUsage = 40 * 1024; // 40MB |
66 | | uint32_t CacheObserver::sMaxDiskChunksMemoryUsage = kDefaultMaxDiskChunksMemoryUsage; |
67 | | |
68 | | static uint32_t const kDefaultMaxDiskPriorityChunksMemoryUsage = 40 * 1024; // 40MB |
69 | | uint32_t CacheObserver::sMaxDiskPriorityChunksMemoryUsage = kDefaultMaxDiskPriorityChunksMemoryUsage; |
70 | | |
71 | | static uint32_t const kDefaultCompressionLevel = 1; |
72 | | uint32_t CacheObserver::sCompressionLevel = kDefaultCompressionLevel; |
73 | | |
74 | | static bool kDefaultSanitizeOnShutdown = false; |
75 | | bool CacheObserver::sSanitizeOnShutdown = kDefaultSanitizeOnShutdown; |
76 | | |
77 | | static bool kDefaultClearCacheOnShutdown = false; |
78 | | bool CacheObserver::sClearCacheOnShutdown = kDefaultClearCacheOnShutdown; |
79 | | |
80 | | static bool kDefaultCacheFSReported = false; |
81 | | bool CacheObserver::sCacheFSReported = kDefaultCacheFSReported; |
82 | | |
83 | | static bool kDefaultHashStatsReported = false; |
84 | | bool CacheObserver::sHashStatsReported = kDefaultHashStatsReported; |
85 | | |
86 | | static uint32_t const kDefaultMaxShutdownIOLag = 2; // seconds |
87 | | Atomic<uint32_t, Relaxed> CacheObserver::sMaxShutdownIOLag(kDefaultMaxShutdownIOLag); |
88 | | |
89 | | Atomic<PRIntervalTime> CacheObserver::sShutdownDemandedTime(PR_INTERVAL_NO_TIMEOUT); |
90 | | |
91 | | NS_IMPL_ISUPPORTS(CacheObserver, |
92 | | nsIObserver, |
93 | | nsISupportsWeakReference) |
94 | | |
95 | | // static |
96 | | nsresult |
97 | | CacheObserver::Init() |
98 | 3 | { |
99 | 3 | if (IsNeckoChild()) { |
100 | 0 | return NS_OK; |
101 | 0 | } |
102 | 3 | |
103 | 3 | if (sSelf) { |
104 | 0 | return NS_OK; |
105 | 0 | } |
106 | 3 | |
107 | 3 | nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); |
108 | 3 | if (!obs) { |
109 | 0 | return NS_ERROR_UNEXPECTED; |
110 | 0 | } |
111 | 3 | |
112 | 3 | sSelf = new CacheObserver(); |
113 | 3 | NS_ADDREF(sSelf); |
114 | 3 | |
115 | 3 | obs->AddObserver(sSelf, "prefservice:after-app-defaults", true); |
116 | 3 | obs->AddObserver(sSelf, "profile-do-change", true); |
117 | 3 | obs->AddObserver(sSelf, "browser-delayed-startup-finished", true); |
118 | 3 | obs->AddObserver(sSelf, "profile-before-change", true); |
119 | 3 | obs->AddObserver(sSelf, "xpcom-shutdown", true); |
120 | 3 | obs->AddObserver(sSelf, "last-pb-context-exited", true); |
121 | 3 | obs->AddObserver(sSelf, "clear-origin-attributes-data", true); |
122 | 3 | obs->AddObserver(sSelf, "memory-pressure", true); |
123 | 3 | |
124 | 3 | return NS_OK; |
125 | 3 | } |
126 | | |
127 | | // static |
128 | | nsresult |
129 | | CacheObserver::Shutdown() |
130 | 0 | { |
131 | 0 | if (!sSelf) { |
132 | 0 | return NS_ERROR_NOT_INITIALIZED; |
133 | 0 | } |
134 | 0 | |
135 | 0 | NS_RELEASE(sSelf); |
136 | 0 | return NS_OK; |
137 | 0 | } |
138 | | |
139 | | void |
140 | | CacheObserver::AttachToPreferences() |
141 | 0 | { |
142 | 0 | mozilla::Preferences::AddBoolVarCache( |
143 | 0 | &sUseDiskCache, "browser.cache.disk.enable", kDefaultUseDiskCache); |
144 | 0 | mozilla::Preferences::AddBoolVarCache( |
145 | 0 | &sUseMemoryCache, "browser.cache.memory.enable", kDefaultUseMemoryCache); |
146 | 0 |
|
147 | 0 | mozilla::Preferences::AddUintVarCache( |
148 | 0 | &sMetadataMemoryLimit, "browser.cache.disk.metadata_memory_limit", kDefaultMetadataMemoryLimit); |
149 | 0 |
|
150 | 0 | mozilla::Preferences::AddAtomicUintVarCache( |
151 | 0 | &sDiskCacheCapacity, "browser.cache.disk.capacity", kDefaultDiskCacheCapacity); |
152 | 0 | mozilla::Preferences::AddBoolVarCache( |
153 | 0 | &sSmartCacheSizeEnabled, "browser.cache.disk.smart_size.enabled", kDefaultSmartCacheSizeEnabled); |
154 | 0 | mozilla::Preferences::AddIntVarCache( |
155 | 0 | &sMemoryCacheCapacity, "browser.cache.memory.capacity", kDefaultMemoryCacheCapacity); |
156 | 0 |
|
157 | 0 | mozilla::Preferences::AddUintVarCache( |
158 | 0 | &sDiskFreeSpaceSoftLimit, "browser.cache.disk.free_space_soft_limit", kDefaultDiskFreeSpaceSoftLimit); |
159 | 0 | mozilla::Preferences::AddUintVarCache( |
160 | 0 | &sDiskFreeSpaceHardLimit, "browser.cache.disk.free_space_hard_limit", kDefaultDiskFreeSpaceHardLimit); |
161 | 0 |
|
162 | 0 | mozilla::Preferences::AddUintVarCache( |
163 | 0 | &sPreloadChunkCount, "browser.cache.disk.preload_chunk_count", kDefaultPreloadChunkCount); |
164 | 0 |
|
165 | 0 | mozilla::Preferences::AddIntVarCache( |
166 | 0 | &sMaxDiskEntrySize, "browser.cache.disk.max_entry_size", kDefaultMaxDiskEntrySize); |
167 | 0 | mozilla::Preferences::AddIntVarCache( |
168 | 0 | &sMaxMemoryEntrySize, "browser.cache.memory.max_entry_size", kDefaultMaxMemoryEntrySize); |
169 | 0 |
|
170 | 0 | mozilla::Preferences::AddUintVarCache( |
171 | 0 | &sMaxDiskChunksMemoryUsage, "browser.cache.disk.max_chunks_memory_usage", kDefaultMaxDiskChunksMemoryUsage); |
172 | 0 | mozilla::Preferences::AddUintVarCache( |
173 | 0 | &sMaxDiskPriorityChunksMemoryUsage, "browser.cache.disk.max_priority_chunks_memory_usage", kDefaultMaxDiskPriorityChunksMemoryUsage); |
174 | 0 |
|
175 | 0 | // http://mxr.mozilla.org/mozilla-central/source/netwerk/cache/nsCacheEntryDescriptor.cpp#367 |
176 | 0 | mozilla::Preferences::AddUintVarCache( |
177 | 0 | &sCompressionLevel, "browser.cache.compression_level", kDefaultCompressionLevel); |
178 | 0 |
|
179 | 0 | mozilla::Preferences::GetComplex( |
180 | 0 | "browser.cache.disk.parent_directory", NS_GET_IID(nsIFile), |
181 | 0 | getter_AddRefs(mCacheParentDirectoryOverride)); |
182 | 0 |
|
183 | 0 | sHalfLifeHours = std::max(0.01F, std::min(1440.0F, mozilla::Preferences::GetFloat( |
184 | 0 | "browser.cache.frecency_half_life_hours", kDefaultHalfLifeHours))); |
185 | 0 |
|
186 | 0 | mozilla::Preferences::AddBoolVarCache( |
187 | 0 | &sSanitizeOnShutdown, "privacy.sanitize.sanitizeOnShutdown", kDefaultSanitizeOnShutdown); |
188 | 0 | mozilla::Preferences::AddBoolVarCache( |
189 | 0 | &sClearCacheOnShutdown, "privacy.clearOnShutdown.cache", kDefaultClearCacheOnShutdown); |
190 | 0 |
|
191 | 0 | mozilla::Preferences::AddAtomicUintVarCache( |
192 | 0 | &sMaxShutdownIOLag, "browser.cache.max_shutdown_io_lag", kDefaultMaxShutdownIOLag); |
193 | 0 | } |
194 | | |
195 | | // static |
196 | | uint32_t CacheObserver::MemoryCacheCapacity() |
197 | 0 | { |
198 | 0 | if (sMemoryCacheCapacity >= 0) |
199 | 0 | return sMemoryCacheCapacity << 10; |
200 | 0 | |
201 | 0 | if (sAutoMemoryCacheCapacity != -1) |
202 | 0 | return sAutoMemoryCacheCapacity; |
203 | 0 | |
204 | 0 | static uint64_t bytes = PR_GetPhysicalMemorySize(); |
205 | 0 | // If getting the physical memory failed, arbitrarily assume |
206 | 0 | // 32 MB of RAM. We use a low default to have a reasonable |
207 | 0 | // size on all the devices we support. |
208 | 0 | if (bytes == 0) |
209 | 0 | bytes = 32 * 1024 * 1024; |
210 | 0 |
|
211 | 0 | // Conversion from unsigned int64_t to double doesn't work on all platforms. |
212 | 0 | // We need to truncate the value at INT64_MAX to make sure we don't |
213 | 0 | // overflow. |
214 | 0 | if (bytes > INT64_MAX) |
215 | 0 | bytes = INT64_MAX; |
216 | 0 |
|
217 | 0 | uint64_t kbytes = bytes >> 10; |
218 | 0 | double kBytesD = double(kbytes); |
219 | 0 | double x = log(kBytesD)/log(2.0) - 14; |
220 | 0 |
|
221 | 0 | int32_t capacity = 0; |
222 | 0 | if (x > 0) { |
223 | 0 | capacity = (int32_t)(x * x / 3.0 + x + 2.0 / 3 + 0.1); // 0.1 for rounding |
224 | 0 | if (capacity > 32) |
225 | 0 | capacity = 32; |
226 | 0 | capacity <<= 20; |
227 | 0 | } |
228 | 0 |
|
229 | 0 | // Result is in bytes. |
230 | 0 | return sAutoMemoryCacheCapacity = capacity; |
231 | 0 | } |
232 | | |
233 | | // static |
234 | | void |
235 | | CacheObserver::SetDiskCacheCapacity(uint32_t aCapacity) |
236 | 0 | { |
237 | 0 | sDiskCacheCapacity = aCapacity >> 10; |
238 | 0 |
|
239 | 0 | if (!sSelf) { |
240 | 0 | return; |
241 | 0 | } |
242 | 0 | |
243 | 0 | if (NS_IsMainThread()) { |
244 | 0 | sSelf->StoreDiskCacheCapacity(); |
245 | 0 | } else { |
246 | 0 | nsCOMPtr<nsIRunnable> event = |
247 | 0 | NewRunnableMethod("net::CacheObserver::StoreDiskCacheCapacity", |
248 | 0 | sSelf, |
249 | 0 | &CacheObserver::StoreDiskCacheCapacity); |
250 | 0 | NS_DispatchToMainThread(event); |
251 | 0 | } |
252 | 0 | } |
253 | | |
254 | | void |
255 | | CacheObserver::StoreDiskCacheCapacity() |
256 | 0 | { |
257 | 0 | mozilla::Preferences::SetInt("browser.cache.disk.capacity", |
258 | 0 | sDiskCacheCapacity); |
259 | 0 | } |
260 | | |
261 | | // static |
262 | | void |
263 | | CacheObserver::SetCacheFSReported() |
264 | 0 | { |
265 | 0 | sCacheFSReported = true; |
266 | 0 |
|
267 | 0 | if (!sSelf) { |
268 | 0 | return; |
269 | 0 | } |
270 | 0 | |
271 | 0 | if (NS_IsMainThread()) { |
272 | 0 | sSelf->StoreCacheFSReported(); |
273 | 0 | } else { |
274 | 0 | nsCOMPtr<nsIRunnable> event = |
275 | 0 | NewRunnableMethod("net::CacheObserver::StoreCacheFSReported", |
276 | 0 | sSelf, |
277 | 0 | &CacheObserver::StoreCacheFSReported); |
278 | 0 | NS_DispatchToMainThread(event); |
279 | 0 | } |
280 | 0 | } |
281 | | |
282 | | void |
283 | | CacheObserver::StoreCacheFSReported() |
284 | 0 | { |
285 | 0 | mozilla::Preferences::SetInt("browser.cache.disk.filesystem_reported", |
286 | 0 | sCacheFSReported); |
287 | 0 | } |
288 | | |
289 | | // static |
290 | | void |
291 | | CacheObserver::SetHashStatsReported() |
292 | 0 | { |
293 | 0 | sHashStatsReported = true; |
294 | 0 |
|
295 | 0 | if (!sSelf) { |
296 | 0 | return; |
297 | 0 | } |
298 | 0 | |
299 | 0 | if (NS_IsMainThread()) { |
300 | 0 | sSelf->StoreHashStatsReported(); |
301 | 0 | } else { |
302 | 0 | nsCOMPtr<nsIRunnable> event = |
303 | 0 | NewRunnableMethod("net::CacheObserver::StoreHashStatsReported", |
304 | 0 | sSelf, |
305 | 0 | &CacheObserver::StoreHashStatsReported); |
306 | 0 | NS_DispatchToMainThread(event); |
307 | 0 | } |
308 | 0 | } |
309 | | |
310 | | void |
311 | | CacheObserver::StoreHashStatsReported() |
312 | 0 | { |
313 | 0 | mozilla::Preferences::SetInt("browser.cache.disk.hashstats_reported", |
314 | 0 | sHashStatsReported); |
315 | 0 | } |
316 | | |
317 | | // static |
318 | | void CacheObserver::ParentDirOverride(nsIFile** aDir) |
319 | 0 | { |
320 | 0 | if (NS_WARN_IF(!aDir)) |
321 | 0 | return; |
322 | 0 | |
323 | 0 | *aDir = nullptr; |
324 | 0 |
|
325 | 0 | if (!sSelf) |
326 | 0 | return; |
327 | 0 | if (!sSelf->mCacheParentDirectoryOverride) |
328 | 0 | return; |
329 | 0 | |
330 | 0 | sSelf->mCacheParentDirectoryOverride->Clone(aDir); |
331 | 0 | } |
332 | | |
333 | | namespace { |
334 | | namespace CacheStorageEvictHelper { |
335 | | |
336 | | nsresult ClearStorage(bool const aPrivate, |
337 | | bool const aAnonymous, |
338 | | OriginAttributes &aOa) |
339 | 0 | { |
340 | 0 | nsresult rv; |
341 | 0 |
|
342 | 0 | aOa.SyncAttributesWithPrivateBrowsing(aPrivate); |
343 | 0 | RefPtr<LoadContextInfo> info = GetLoadContextInfo(aAnonymous, aOa); |
344 | 0 |
|
345 | 0 | nsCOMPtr<nsICacheStorage> storage; |
346 | 0 | RefPtr<CacheStorageService> service = CacheStorageService::Self(); |
347 | 0 | NS_ENSURE_TRUE(service, NS_ERROR_FAILURE); |
348 | 0 |
|
349 | 0 | // Clear disk storage |
350 | 0 | rv = service->DiskCacheStorage(info, false, getter_AddRefs(storage)); |
351 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
352 | 0 | rv = storage->AsyncEvictStorage(nullptr); |
353 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
354 | 0 |
|
355 | 0 | // Clear memory storage |
356 | 0 | rv = service->MemoryCacheStorage(info, getter_AddRefs(storage)); |
357 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
358 | 0 | rv = storage->AsyncEvictStorage(nullptr); |
359 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
360 | 0 |
|
361 | 0 | return NS_OK; |
362 | 0 | } |
363 | | |
364 | | nsresult Run(OriginAttributes &aOa) |
365 | 0 | { |
366 | 0 | nsresult rv; |
367 | 0 |
|
368 | 0 | // Clear all [private X anonymous] combinations |
369 | 0 | rv = ClearStorage(false, false, aOa); |
370 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
371 | 0 | rv = ClearStorage(false, true, aOa); |
372 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
373 | 0 | rv = ClearStorage(true, false, aOa); |
374 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
375 | 0 | rv = ClearStorage(true, true, aOa); |
376 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
377 | 0 |
|
378 | 0 | return NS_OK; |
379 | 0 | } |
380 | | |
381 | | } // CacheStorageEvictHelper |
382 | | } // anon |
383 | | |
384 | | // static |
385 | | bool CacheObserver::EntryIsTooBig(int64_t aSize, bool aUsingDisk) |
386 | 0 | { |
387 | 0 | // If custom limit is set, check it. |
388 | 0 | int64_t preferredLimit = aUsingDisk ? sMaxDiskEntrySize : sMaxMemoryEntrySize; |
389 | 0 |
|
390 | 0 | // do not convert to bytes when the limit is -1, which means no limit |
391 | 0 | if (preferredLimit > 0) { |
392 | 0 | preferredLimit <<= 10; |
393 | 0 | } |
394 | 0 |
|
395 | 0 | if (preferredLimit != -1 && aSize > preferredLimit) |
396 | 0 | return true; |
397 | 0 | |
398 | 0 | // Otherwise (or when in the custom limit), check limit based on the global |
399 | 0 | // limit. It's 1/8 (>> 3) of the respective capacity. |
400 | 0 | int64_t derivedLimit = aUsingDisk |
401 | 0 | ? (static_cast<int64_t>(DiskCacheCapacity() >> 3)) |
402 | 0 | : (static_cast<int64_t>(MemoryCacheCapacity() >> 3)); |
403 | 0 |
|
404 | 0 | if (aSize > derivedLimit) |
405 | 0 | return true; |
406 | 0 | |
407 | 0 | return false; |
408 | 0 | } |
409 | | |
410 | | // static |
411 | | bool CacheObserver::IsPastShutdownIOLag() |
412 | 0 | { |
413 | | #ifdef DEBUG |
414 | | return false; |
415 | | #endif |
416 | |
|
417 | 0 | if (sShutdownDemandedTime == PR_INTERVAL_NO_TIMEOUT || |
418 | 0 | sMaxShutdownIOLag == UINT32_MAX) { |
419 | 0 | return false; |
420 | 0 | } |
421 | 0 | |
422 | 0 | static const PRIntervalTime kMaxShutdownIOLag = |
423 | 0 | PR_SecondsToInterval(sMaxShutdownIOLag); |
424 | 0 |
|
425 | 0 | if ((PR_IntervalNow() - sShutdownDemandedTime) > kMaxShutdownIOLag) { |
426 | 0 | return true; |
427 | 0 | } |
428 | 0 | |
429 | 0 | return false; |
430 | 0 | } |
431 | | |
432 | | NS_IMETHODIMP |
433 | | CacheObserver::Observe(nsISupports* aSubject, |
434 | | const char* aTopic, |
435 | | const char16_t* aData) |
436 | 0 | { |
437 | 0 | if (!strcmp(aTopic, "prefservice:after-app-defaults")) { |
438 | 0 | CacheFileIOManager::Init(); |
439 | 0 | return NS_OK; |
440 | 0 | } |
441 | 0 | |
442 | 0 | if (!strcmp(aTopic, "profile-do-change")) { |
443 | 0 | AttachToPreferences(); |
444 | 0 | CacheFileIOManager::Init(); |
445 | 0 | CacheFileIOManager::OnProfile(); |
446 | 0 | return NS_OK; |
447 | 0 | } |
448 | 0 | |
449 | 0 | if (!strcmp(aTopic, "browser-delayed-startup-finished")) { |
450 | 0 | CacheStorageService::CleaupCacheDirectories(); |
451 | 0 | return NS_OK; |
452 | 0 | } |
453 | 0 | |
454 | 0 | if (!strcmp(aTopic, "profile-change-net-teardown") || |
455 | 0 | !strcmp(aTopic, "profile-before-change") || |
456 | 0 | !strcmp(aTopic, "xpcom-shutdown")) { |
457 | 0 | if (sShutdownDemandedTime == PR_INTERVAL_NO_TIMEOUT) { |
458 | 0 | sShutdownDemandedTime = PR_IntervalNow(); |
459 | 0 | } |
460 | 0 |
|
461 | 0 | RefPtr<CacheStorageService> service = CacheStorageService::Self(); |
462 | 0 | if (service) { |
463 | 0 | service->Shutdown(); |
464 | 0 | } |
465 | 0 |
|
466 | 0 | CacheFileIOManager::Shutdown(); |
467 | 0 | return NS_OK; |
468 | 0 | } |
469 | 0 |
|
470 | 0 | if (!strcmp(aTopic, "last-pb-context-exited")) { |
471 | 0 | RefPtr<CacheStorageService> service = CacheStorageService::Self(); |
472 | 0 | if (service) { |
473 | 0 | service->DropPrivateBrowsingEntries(); |
474 | 0 | } |
475 | 0 |
|
476 | 0 | return NS_OK; |
477 | 0 | } |
478 | 0 |
|
479 | 0 | if (!strcmp(aTopic, "clear-origin-attributes-data")) { |
480 | 0 | OriginAttributes oa; |
481 | 0 | if (!oa.Init(nsDependentString(aData))) { |
482 | 0 | NS_ERROR("Could not parse OriginAttributes JSON in clear-origin-attributes-data notification"); |
483 | 0 | return NS_OK; |
484 | 0 | } |
485 | 0 |
|
486 | 0 | nsresult rv = CacheStorageEvictHelper::Run(oa); |
487 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
488 | 0 |
|
489 | 0 | return NS_OK; |
490 | 0 | } |
491 | 0 | |
492 | 0 | if (!strcmp(aTopic, "memory-pressure")) { |
493 | 0 | RefPtr<CacheStorageService> service = CacheStorageService::Self(); |
494 | 0 | if (service) |
495 | 0 | service->PurgeFromMemory(nsICacheStorageService::PURGE_EVERYTHING); |
496 | 0 |
|
497 | 0 | return NS_OK; |
498 | 0 | } |
499 | 0 |
|
500 | 0 | MOZ_ASSERT(false, "Missing observer handler"); |
501 | 0 | return NS_OK; |
502 | 0 | } |
503 | | |
504 | | } // namespace net |
505 | | } // namespace mozilla |