From f2b6cb61ab5b6d30c80735ca4d553b1dd979a788 Mon Sep 17 00:00:00 2001 From: Jason Duell Date: Fri, 28 Sep 2012 16:13:17 -0700 Subject: [PATCH] Bug 786299 - Part 2: Delete app-cache related to an app when uninstalled. r=honza --- layout/build/nsLayoutStatics.cpp | 2 + netwerk/base/public/nsNetUtil.h | 41 +++++++++++++++ netwerk/cache/Makefile.in | 1 + netwerk/cache/nsApplicationCacheService.cpp | 57 ++++++++++++++++++++- netwerk/cache/nsApplicationCacheService.h | 6 +++ 5 files changed, 106 insertions(+), 1 deletion(-) diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index ec764dcdffd..e2316821f83 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -101,6 +101,7 @@ #include "mozilla/dom/ipc/ProcessPriorityManager.h" #include "nsPermissionManager.h" #include "nsCookieService.h" +#include "nsApplicationCacheService.h" extern void NS_ShutdownChainItemPool(); @@ -257,6 +258,7 @@ nsLayoutStatics::Initialize() nsPermissionManager::AppUninstallObserverInit(); nsCookieService::AppUninstallObserverInit(); + nsApplicationCacheService::AppClearDataObserverInit(); nsDOMStorageBaseDB::Init(); diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 923b5cd09f5..0229e5efe62 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -77,6 +77,7 @@ #include "nsILoadContext.h" #include "mozilla/Services.h" #include "nsIPrivateBrowsingChannel.h" +#include "mozIApplicationClearPrivateDataParams.h" #include @@ -1334,6 +1335,46 @@ NS_GetAppInfo(nsIChannel *aChannel, uint32_t *aAppID, bool *aIsInBrowserElement) return true; } +#define TOPIC_WEB_APP_CLEAR_DATA "webapps-clear-data" + +/** + * Gets appId and browserOnly parameters from the TOPIC_WEB_APP_CLEAR_DATA + * nsIObserverService notification. Used when clearing user data or + * uninstalling web apps. + */ +inline nsresult +NS_GetAppInfoFromClearDataNotification(nsISupports *aSubject, + uint32_t *aAppID, bool* aBrowserOnly) +{ + nsresult rv; + + nsCOMPtr + clearParams(do_QueryInterface(aSubject)); + MOZ_ASSERT(clearParams); + if (!clearParams) { + return NS_ERROR_UNEXPECTED; + } + + uint32_t appId; + rv = clearParams->GetAppId(&appId); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + MOZ_ASSERT(appId != NECKO_NO_APP_ID); + MOZ_ASSERT(appId != NECKO_UNKNOWN_APP_ID); + NS_ENSURE_SUCCESS(rv, rv); + if (appId == NECKO_NO_APP_ID || appId == NECKO_UNKNOWN_APP_ID) { + return NS_ERROR_UNEXPECTED; + } + + bool browserOnly = false; + rv = clearParams->GetBrowserOnly(&browserOnly); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + NS_ENSURE_SUCCESS(rv, rv); + + *aAppID = appId; + *aBrowserOnly = browserOnly; + return NS_OK; +} + /** * Wraps an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2. This * method is provided mainly for use by other methods in this file. diff --git a/netwerk/cache/Makefile.in b/netwerk/cache/Makefile.in index f525a9a85be..8c6b9a8d2d4 100644 --- a/netwerk/cache/Makefile.in +++ b/netwerk/cache/Makefile.in @@ -30,6 +30,7 @@ XPIDLSRCS = \ EXPORTS = \ nsCacheService.h \ + nsApplicationCacheService.h \ $(NULL) CPPSRCS = \ diff --git a/netwerk/cache/nsApplicationCacheService.cpp b/netwerk/cache/nsApplicationCacheService.cpp index b494988cbb4..89e3ebb71e2 100644 --- a/netwerk/cache/nsApplicationCacheService.cpp +++ b/netwerk/cache/nsApplicationCacheService.cpp @@ -6,13 +6,18 @@ #include "nsDiskCacheDeviceSQL.h" #include "nsCacheService.h" #include "nsApplicationCacheService.h" - +#include "nsCRT.h" #include "nsNetUtil.h" +#include "nsIObserverService.h" using namespace mozilla; static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID); +//----------------------------------------------------------------------------- +// nsApplicationCacheService +//----------------------------------------------------------------------------- + NS_IMPL_ISUPPORTS1(nsApplicationCacheService, nsIApplicationCacheService) nsApplicationCacheService::nsApplicationCacheService() @@ -166,3 +171,53 @@ nsApplicationCacheService::GetGroupsTimeOrdered(uint32_t *count, NS_ENSURE_SUCCESS(rv, rv); return device->GetGroupsTimeOrdered(count, keys); } + +//----------------------------------------------------------------------------- +// AppCacheClearDataObserver: handles clearing appcache data for app uninstall +// and clearing user data events. +//----------------------------------------------------------------------------- + +namespace { + +class AppCacheClearDataObserver MOZ_FINAL : public nsIObserver { +public: + NS_DECL_ISUPPORTS + + // nsIObserver implementation. + NS_IMETHODIMP + Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) + { + MOZ_ASSERT(!nsCRT::strcmp(aTopic, TOPIC_WEB_APP_CLEAR_DATA)); + + uint32_t appId = NECKO_UNKNOWN_APP_ID; + bool browserOnly = false; + nsresult rv = NS_GetAppInfoFromClearDataNotification(aSubject, &appId, + &browserOnly); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr cacheService = + do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return cacheService->DiscardByAppId(appId, browserOnly); + } +}; + +NS_IMPL_ISUPPORTS1(AppCacheClearDataObserver, nsIObserver) + +} // anonymous namespace + +// Instantiates and registers AppCacheClearDataObserver for notifications +void +nsApplicationCacheService::AppClearDataObserverInit() +{ + nsCOMPtr observerService = + do_GetService("@mozilla.org/observer-service;1"); + if (observerService) { + nsRefPtr obs + = new AppCacheClearDataObserver(); + observerService->AddObserver(obs, TOPIC_WEB_APP_CLEAR_DATA, + /*holdsWeak=*/ false); + } +} + diff --git a/netwerk/cache/nsApplicationCacheService.h b/netwerk/cache/nsApplicationCacheService.h index 228fa3ddb7f..4580f5cbb18 100644 --- a/netwerk/cache/nsApplicationCacheService.h +++ b/netwerk/cache/nsApplicationCacheService.h @@ -5,8 +5,11 @@ #ifndef _nsApplicationCacheService_h_ #define _nsApplicationCacheService_h_ +#include "nsIApplicationCacheService.h" #include "mozilla/Attributes.h" +class nsCacheService; + class nsApplicationCacheService MOZ_FINAL : public nsIApplicationCacheService { public: @@ -14,6 +17,9 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIAPPLICATIONCACHESERVICE + + static void AppClearDataObserverInit(); + private: nsresult GetJARIdentifier(nsIURI *aURI, nsILoadContext *aLoadContext,