Commit f861b390 authored by yoshiki@chromium.org's avatar yoshiki@chromium.org

Drive: add a method to clear all local cache.

Mainly, this cl add the two methods to clear cache.
1) GDataCache::ClearAllOnUIThread():
- remove all the files in the cache directory.
- re-create the |metadata_| instance.
2) GDataSystemService::ClearCacheAndReset():
- unmount Drive
- cancel all the running tasks.
- call GDataCache::ClearAllOnUIThread()
- re-mount Drive

BUG=135197
TEST=out/Debug/unit_tests:GData* and out/Debug/browser_tests:GData* passes.

Review URL: https://chromiumcodereview.appspot.com/10823125

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149914 0039d316-1c4b-4281-b951-d872f2087c98
parent faf8f229
......@@ -363,7 +363,7 @@ void FileBrowserEventRouter::MountCompleted(
system_service ? system_service->cache() : NULL;
if (cache) {
cache->SetMountedStateOnUIThread(
source_path, false, gdata::SetMountedStateCallback());
source_path, false, gdata::ChangeCacheStateCallback());
}
}
}
......
......@@ -238,10 +238,10 @@ void CollectAnyFile(std::vector<std::string>* resource_ids,
}
// Runs callback with pointers dereferenced.
// Used to implement SetMountedStateOnUIThread.
void RunSetMountedStateCallback(const SetMountedStateCallback& callback,
GDataFileError* error,
FilePath* cache_file_path) {
// Used to implement SetMountedStateOnUIThread and ClearAllOnUIThread.
void RunChangeCacheStateCallback(const ChangeCacheStateCallback& callback,
const GDataFileError* error,
const FilePath* cache_file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(error);
DCHECK(cache_file_path);
......@@ -573,7 +573,7 @@ void GDataCache::UnpinOnUIThread(const std::string& resource_id,
void GDataCache::SetMountedStateOnUIThread(
const FilePath& file_path,
bool to_mount,
const SetMountedStateCallback& callback) {
const ChangeCacheStateCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GDataFileError* error =
......@@ -587,7 +587,7 @@ void GDataCache::SetMountedStateOnUIThread(
to_mount,
error,
cache_file_path),
base::Bind(&RunSetMountedStateCallback,
base::Bind(&RunChangeCacheStateCallback,
callback,
base::Owned(error),
base::Owned(cache_file_path)));
......@@ -682,6 +682,22 @@ void GDataCache::RemoveOnUIThread(const std::string& resource_id,
"" /* md5 */));
}
void GDataCache::ClearAllOnUIThread(const ChangeCacheStateCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GDataFileError* error = new GDataFileError(GDATA_FILE_OK);
blocking_task_runner_->PostTaskAndReply(
FROM_HERE,
base::Bind(&GDataCache::ClearAll,
base::Unretained(this),
error),
base::Bind(&RunChangeCacheStateCallback,
callback,
base::Owned(error),
&cache_root_path_));
}
void GDataCache::RequestInitializeOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......@@ -1435,6 +1451,16 @@ void GDataCache::Remove(const std::string& resource_id,
*error = GDATA_FILE_OK;
}
void GDataCache::ClearAll(GDataFileError* error) {
AssertOnSequencedWorkerPool();
DCHECK(error);
bool success = file_util::Delete(cache_root_path_, true);
Initialize();
*error = success ? GDATA_FILE_OK : GDATA_FILE_ERROR_FAILED;
}
void GDataCache::OnPinned(GDataFileError* error,
const std::string& resource_id,
const std::string& md5,
......
......@@ -30,9 +30,10 @@ namespace gdata {
class GDataCacheEntry;
class GDataCacheMetadata;
// Callback for SetMountedStateOnUIThread.
// Callback for SetMountedStateOnUIThread and ClearAllOnUIThread.
typedef base::Callback<void(GDataFileError error,
const FilePath& file_path)> SetMountedStateCallback;
const FilePath& file_path)>
ChangeCacheStateCallback;
// Callback for completion of cache operation.
typedef base::Callback<void(GDataFileError error,
......@@ -229,7 +230,7 @@ class GDataCache {
// |dest_path| is the mounted path and |source_path| the unmounted path.
void SetMountedStateOnUIThread(const FilePath& file_path,
bool to_mount,
const SetMountedStateCallback& callback);
const ChangeCacheStateCallback& callback);
// Modifies cache state, which involves the following:
// - moves |source_path| to |dest_path| in persistent dir, where
......@@ -263,6 +264,11 @@ class GDataCache {
void RemoveOnUIThread(const std::string& resource_id,
const CacheOperationCallback& callback);
// Does the following:
// - remove all the files in the cache directory.
// - re-create the |metadata_| instance.
void ClearAllOnUIThread(const ChangeCacheStateCallback& callback);
// Utility method to call Initialize on UI thread.
void RequestInitializeOnUIThread();
......@@ -396,6 +402,9 @@ class GDataCache {
void Remove(const std::string& resource_id,
GDataFileError* error);
// Used to implement ClearAllUIThread.
void ClearAll(GDataFileError* error);
// Runs callback and notifies the observers when file is pinned.
void OnPinned(GDataFileError* error,
const std::string& resource_id,
......
......@@ -113,6 +113,15 @@ void OnGetResourceIds(std::vector<std::string>* out_resource_ids,
*out_resource_ids = resource_ids;
}
// Copies results from ClearAllOnUIThread.
void OnClearAll(GDataFileError* out_error,
FilePath* out_file_path,
GDataFileError error,
const FilePath& file_path) {
*out_file_path = file_path;
*out_error = error;
}
} // namespace
class GDataCacheTest : public testing::Test {
......@@ -717,6 +726,31 @@ class GDataCacheTest : public testing::Test {
EXPECT_EQ(resource_id, unescaped_resource_id);
}
// Returns the number of the cache files with name <resource_id>, and Confirm
// that they have the <md5>. This should return 1 or 0.
size_t CountCacheFiles(const std::string& resource_id,
const std::string& md5) {
FilePath path = GetCacheFilePath(
resource_id, "*",
(test_util::ToCacheEntry(expected_cache_state_).is_pinned() ?
GDataCache::CACHE_TYPE_PERSISTENT :
GDataCache::CACHE_TYPE_TMP),
GDataCache::CACHED_FILE_FROM_SERVER);
file_util::FileEnumerator enumerator(path.DirName(), false,
file_util::FileEnumerator::FILES,
path.BaseName().value());
size_t num_files_found = 0;
for (FilePath current = enumerator.Next(); !current.empty();
current = enumerator.Next()) {
++num_files_found;
EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
FilePath::kExtensionSeparator +
util::EscapeCacheFileName(md5),
current.BaseName().value());
}
return num_files_found;
}
static FilePath GetTestFilePath(const FilePath::StringType& filename) {
FilePath path;
std::string error;
......@@ -805,25 +839,7 @@ TEST_F(GDataCacheTest, StoreToCacheSimple) {
// Verify that there's only one file with name <resource_id>, i.e. previously
// cached file with the different md5 should be deleted.
FilePath path = GetCacheFilePath(
resource_id, "*",
(test_util::ToCacheEntry(expected_cache_state_).is_pinned() ?
GDataCache::CACHE_TYPE_PERSISTENT :
GDataCache::CACHE_TYPE_TMP),
GDataCache::CACHED_FILE_FROM_SERVER);
file_util::FileEnumerator enumerator(path.DirName(), false,
file_util::FileEnumerator::FILES,
path.BaseName().value());
size_t num_files_found = 0;
for (FilePath current = enumerator.Next(); !current.empty();
current = enumerator.Next()) {
++num_files_found;
EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
FilePath::kExtensionSeparator +
util::EscapeCacheFileName(md5),
current.BaseName().value());
}
EXPECT_EQ(1U, num_files_found);
EXPECT_EQ(1U, CountCacheFiles(resource_id, md5));
}
TEST_F(GDataCacheTest, GetFromCacheSimple) {
......@@ -1461,4 +1477,34 @@ TEST_F(GDataCacheTest, GetResourceIdsOfAllFilesOnUIThread) {
EXPECT_EQ("tmp:resource_id", resource_ids[5]);
}
TEST_F(GDataCacheTest, ClearAllOnUIThread) {
PrepareForInitCacheTest();
std::string resource_id("pdf:1a2b");
std::string md5("abcdef0123456789");
// Store an existing file.
TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
GDataCache::CACHE_TYPE_TMP);
EXPECT_EQ(1, num_callback_invocations_);
// Verify that there's only one cached file.
EXPECT_EQ(1U, CountCacheFiles(resource_id, md5));
// Clear cache.
GDataFileError error = GDATA_FILE_OK;
FilePath file_path;
cache_->ClearAllOnUIThread(base::Bind(&OnClearAll,
&error,
&file_path));
test_util::RunBlockingPoolTask();
EXPECT_EQ(GDATA_FILE_OK, error);
// Verify that all the cache is removed.
VerifyRemoveFromCache(error, resource_id, md5);
EXPECT_EQ(0U, CountCacheFiles(resource_id, md5));
}
} // namespace gdata
......@@ -40,7 +40,8 @@ const std::string* g_test_cache_root = NULL;
GDataSystemService::GDataSystemService(Profile* profile)
: profile_(profile),
cache_(NULL) {
cache_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::SequencedWorkerPool* blocking_pool = BrowserThread::GetBlockingPool();
blocking_task_runner_ = blocking_pool->GetSequencedTaskRunner(
......@@ -106,6 +107,30 @@ void GDataSystemService::Shutdown() {
documents_service_.reset();
}
void GDataSystemService::ClearCacheAndRemountFileSystem(
const base::Callback<void(bool)>& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
RemoveDriveMountPoint();
docs_service()->CancelAll();
cache_->ClearAllOnUIThread(
base::Bind(&GDataSystemService::AddBackDriveMountPoint,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
void GDataSystemService::AddBackDriveMountPoint(
const base::Callback<void(bool)>& callback,
GDataFileError error,
const FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
AddDriveMountPoint();
if (!callback.is_null())
callback.Run(error == GDATA_FILE_OK);
}
void GDataSystemService::AddDriveMountPoint() {
if (!gdata::util::IsGDataAvailable(profile_))
return;
......
......@@ -9,7 +9,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/chromeos/gdata/gdata_errorcode.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
......@@ -43,6 +45,11 @@ class GDataSystemService : public ProfileKeyedService {
GDataContactsService* contacts_service() { return contacts_service_.get(); }
DriveWebAppsRegistry* webapps_registry() { return webapps_registry_.get(); }
// Clears all the local cache files and in-memory data, and remounts the file
// system.
void ClearCacheAndRemountFileSystem(
const base::Callback<void(bool)>& callback);
// ProfileKeyedService override:
virtual void Shutdown() OVERRIDE;
......@@ -60,6 +67,11 @@ class GDataSystemService : public ProfileKeyedService {
// Unregisters drive mount point from File API.
void RemoveDriveMountPoint();
// Adds back the drive mount point. Used to implement ClearCache().
void AddBackDriveMountPoint(const base::Callback<void(bool)>& callback,
GDataFileError error,
const FilePath& file_path);
friend class GDataSystemServiceFactory;
Profile* profile_;
......@@ -73,6 +85,7 @@ class GDataSystemService : public ProfileKeyedService {
scoped_ptr<GDataDownloadObserver> download_observer_;
scoped_ptr<GDataSyncClient> sync_client_;
scoped_ptr<GDataContactsService> contacts_service_;
base::WeakPtrFactory<GDataSystemService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(GDataSystemService);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment