summaryrefslogtreecommitdiffstats
path: root/chrome/browser/appcache
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/appcache')
-rw-r--r--chrome/browser/appcache/chrome_appcache_service.cc46
-rw-r--r--chrome/browser/appcache/chrome_appcache_service.h11
-rw-r--r--chrome/browser/appcache/chrome_appcache_service_unittest.cc99
3 files changed, 145 insertions, 11 deletions
diff --git a/chrome/browser/appcache/chrome_appcache_service.cc b/chrome/browser/appcache/chrome_appcache_service.cc
index c01b1d7..6c84999 100644
--- a/chrome/browser/appcache/chrome_appcache_service.cc
+++ b/chrome/browser/appcache/chrome_appcache_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,20 @@
static bool has_initialized_thread_ids;
+namespace {
+
+// Used to defer deleting of local storage until the destructor has finished.
+void DeleteLocalStateOnIOThread(FilePath cache_path) {
+ // Post the actual deletion to the DB thread to ensure it happens after the
+ // database file has been closed.
+ BrowserThread::PostTask(
+ BrowserThread::DB, FROM_HERE,
+ NewRunnableFunction<bool(*)(const FilePath&, bool), FilePath, bool>(
+ &file_util::Delete, cache_path, true));
+}
+
+} // namespace
+
// ----------------------------------------------------------------------------
ChromeAppCacheService::ChromeAppCacheService() {
@@ -22,7 +36,8 @@ ChromeAppCacheService::ChromeAppCacheService() {
void ChromeAppCacheService::InitializeOnIOThread(
const FilePath& profile_path, bool is_incognito,
- scoped_refptr<HostContentSettingsMap> content_settings_map) {
+ scoped_refptr<HostContentSettingsMap> content_settings_map,
+ bool clear_local_state_on_exit) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!has_initialized_thread_ids) {
@@ -33,16 +48,24 @@ void ChromeAppCacheService::InitializeOnIOThread(
host_contents_settings_map_ = content_settings_map;
registrar_.Add(
this, NotificationType::PURGE_MEMORY, NotificationService::AllSources());
+ SetClearLocalStateOnExit(clear_local_state_on_exit);
+ if (!is_incognito)
+ cache_path_ = profile_path.Append(chrome::kAppCacheDirname);
// Init our base class.
- Initialize(
- is_incognito ? FilePath() : profile_path.Append(chrome::kAppCacheDirname),
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
+ Initialize(cache_path_,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
set_appcache_policy(this);
}
ChromeAppCacheService::~ChromeAppCacheService() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (clear_local_state_on_exit_ && !cache_path_.empty()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(DeleteLocalStateOnIOThread, cache_path_));
+ }
}
void ChromeAppCacheService::SetOriginQuotaInMemory(
@@ -58,9 +81,16 @@ void ChromeAppCacheService::ResetOriginQuotaInMemory(const GURL& origin) {
storage()->ResetOriginQuotaInMemory(origin);
}
-// static
-void ChromeAppCacheService::ClearLocalState(const FilePath& profile_path) {
- file_util::Delete(profile_path.Append(chrome::kAppCacheDirname), true);
+void ChromeAppCacheService::SetClearLocalStateOnExit(bool clear_local_state) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this,
+ &ChromeAppCacheService::SetClearLocalStateOnExit,
+ clear_local_state));
+ return;
+ }
+ clear_local_state_on_exit_ = clear_local_state;
}
bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
diff --git a/chrome/browser/appcache/chrome_appcache_service.h b/chrome/browser/appcache/chrome_appcache_service.h
index dbc0616..0b43759 100644
--- a/chrome/browser/appcache/chrome_appcache_service.h
+++ b/chrome/browser/appcache/chrome_appcache_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,14 +35,15 @@ class ChromeAppCacheService
void InitializeOnIOThread(
const FilePath& profile_path, bool is_incognito,
- scoped_refptr<HostContentSettingsMap> content_settings_map);
+ scoped_refptr<HostContentSettingsMap> content_settings_map,
+ bool clear_local_state_on_exit);
// Helpers used by the extension service to grant and revoke
// unlimited storage to app extensions.
void SetOriginQuotaInMemory(const GURL& origin, int64 quota);
void ResetOriginQuotaInMemory(const GURL& origin);
- static void ClearLocalState(const FilePath& profile_path);
+ void SetClearLocalStateOnExit(bool clear_local_state);
private:
friend class BrowserThread;
@@ -62,6 +63,10 @@ class ChromeAppCacheService
scoped_refptr<HostContentSettingsMap> host_contents_settings_map_;
NotificationRegistrar registrar_;
+ bool clear_local_state_on_exit_;
+ FilePath cache_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeAppCacheService);
};
#endif // CHROME_BROWSER_APPCACHE_CHROME_APPCACHE_SERVICE_H_
diff --git a/chrome/browser/appcache/chrome_appcache_service_unittest.cc b/chrome/browser/appcache/chrome_appcache_service_unittest.cc
new file mode 100644
index 0000000..0cb5090
--- /dev/null
+++ b/chrome/browser/appcache/chrome_appcache_service_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_temp_dir.h"
+#include "chrome/browser/appcache/chrome_appcache_service.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/test/thread_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/appcache/appcache_storage_impl.h"
+
+namespace appcache {
+
+class ChromeAppCacheServiceTest : public testing::Test {
+ public:
+ ChromeAppCacheServiceTest()
+ : message_loop_(MessageLoop::TYPE_IO),
+ db_thread_(BrowserThread::DB, &message_loop_),
+ file_thread_(BrowserThread::FILE, &message_loop_),
+ cache_thread_(BrowserThread::CACHE, &message_loop_),
+ io_thread_(BrowserThread::IO, &message_loop_) {
+ }
+
+ protected:
+ MessageLoop message_loop_;
+ ScopedTempDir temp_dir_;
+
+ private:
+ BrowserThread db_thread_;
+ BrowserThread file_thread_;
+ BrowserThread cache_thread_;
+ BrowserThread io_thread_;
+};
+
+TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname);
+ scoped_refptr<ChromeAppCacheService> appcache_service =
+ new ChromeAppCacheService;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(appcache_service.get(),
+ &ChromeAppCacheService::InitializeOnIOThread,
+ temp_dir_.path(), false,
+ scoped_refptr<HostContentSettingsMap>(NULL),
+ false));
+ // Make the steps needed to initialize the storage of AppCache data.
+ message_loop_.RunAllPending();
+ appcache::AppCacheStorageImpl* storage =
+ static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage());
+ ASSERT_TRUE(storage->database_->db_connection());
+ ASSERT_EQ(1, storage->NewCacheId());
+ storage->disk_cache();
+ message_loop_.RunAllPending();
+
+ ASSERT_TRUE(file_util::PathExists(appcache_path));
+ ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index")));
+
+ appcache_service = NULL;
+ message_loop_.RunAllPending();
+
+ ASSERT_TRUE(file_util::PathExists(appcache_path));
+}
+
+TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname);
+ scoped_refptr<ChromeAppCacheService> appcache_service =
+ new ChromeAppCacheService;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(appcache_service.get(),
+ &ChromeAppCacheService::InitializeOnIOThread,
+ temp_dir_.path(), false,
+ scoped_refptr<HostContentSettingsMap>(NULL),
+ true));
+ // Make the steps needed to initialize the storage of AppCache data.
+ message_loop_.RunAllPending();
+ appcache::AppCacheStorageImpl* storage =
+ static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage());
+ ASSERT_TRUE(storage->database_->db_connection());
+ ASSERT_EQ(1, storage->NewCacheId());
+ storage->disk_cache();
+ message_loop_.RunAllPending();
+
+ ASSERT_TRUE(file_util::PathExists(appcache_path));
+ ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index")));
+
+ appcache_service = NULL;
+ message_loop_.RunAllPending();
+
+ ASSERT_FALSE(file_util::PathExists(appcache_path));
+}
+
+} // namespace appcache