resource_metadata.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stringprintf.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/sys_info.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata_storage.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::BrowserThread; 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace drive { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Sets entry's base name from its title and other attributes. 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetBaseNameFromTitle(ResourceEntry* entry) { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string base_name = entry->title(); 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry->has_file_specific_info() && 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->file_specific_info().is_hosted_document()) { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base_name += entry->file_specific_info().document_extension(); 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->set_base_name(util::EscapeUtf8FileName(base_name)); 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates an entry by copying |source|, and setting the base name properly. 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceEntry CreateEntryWithProperBaseName(const ResourceEntry& source) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry entry(source); 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetBaseNameFromTitle(&entry); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return entry; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs |callback| with |result|. Used to implement GetChildDirectories(). 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RunGetChildDirectoriesCallbackWithResult( 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetChildDirectoriesCallback& callback, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<std::set<base::FilePath> > result) { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(*result); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true if enough disk space is avilable for DB operation. 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kRequiredDiskSpaceInMB = 128; // 128 MB seems to be large enough. 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::SysInfo::AmountOfFreeDiskSpace(path) >= 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kRequiredDiskSpaceInMB * (1 << 20); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs |callback| with arguments. 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RunGetResourceEntryCallback(const GetResourceEntryCallback& callback, 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<ResourceEntry> entry, 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) FileError error) { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != FILE_ERROR_OK) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry.reset(); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error, entry.Pass()); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs |callback| with arguments. 65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RunGetResourceEntryWithFilePathCallback( 66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryWithFilePathCallback& callback, 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* path, 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error) { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(path); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != FILE_ERROR_OK) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry.reset(); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error, *path, entry.Pass()); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs |callback| with arguments. 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RunReadDirectoryCallback(const ReadDirectoryCallback& callback, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntryVector> entries, 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != FILE_ERROR_OK) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries.reset(); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error, entries.Pass()); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs |callback| with arguments. 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RunFileMoveCallback(const FileMoveCallback& callback, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* path, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(path); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error, *path); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Helper function to run tasks with FileMoveCallback. 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PostFileMoveTask( 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TaskRunner* task_runner, 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<FileError(base::FilePath* out_file_path)>& task, 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileMoveCallback& callback) { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!task.is_null()); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* file_path = new base::FilePath; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) task_runner, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(task, file_path), 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&RunFileMoveCallback, callback, base::Owned(file_path))); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string DirectoryFetchInfo::ToString() const { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ("resource_id: " + resource_id_ + 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ", changestamp: " + base::Int64ToString(changestamp_)); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EntryInfoResult::EntryInfoResult() : error(FILE_ERROR_FAILED) { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EntryInfoResult::~EntryInfoResult() { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EntryInfoPairResult::EntryInfoPairResult() { 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)EntryInfoPairResult::~EntryInfoPairResult() { 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace internal { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::ResourceMetadata( 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& data_directory_path, 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : data_directory_path_(data_directory_path), 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_(blocking_task_runner), 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_(new ResourceMetadataStorage(data_directory_path)), 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::Initialize(const FileOperationCallback& callback) { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ResourceMetadata::InitializeOnBlockingPool, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::Destroy() { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_->PostTask( 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ResourceMetadata::DestroyOnBlockingPool, 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::ResetOnUIThread(const FileOperationCallback& callback) { 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::Reset, 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::Reset() { 183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!storage_->SetLargestChangestamp(0) || 189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !RemoveEntryRecursively(util::kDriveGrandRootSpecialResourceId) || 190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) !SetUpDefaultEntries()) 191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_FAILED; 192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::~ResourceMetadata() { 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileError ResourceMetadata::InitializeOnBlockingPool() { 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the storage. 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!storage_->Initialize()) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_FAILED; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!SetUpDefaultEntries()) 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_FAILED; 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_OK; 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ResourceMetadata::SetUpDefaultEntries() { 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the grand root and "other" entries. "/drive" and "/drive/other". 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // As an intermediate change, "/drive/root" is also added here. 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!storage_->GetEntry(util::kDriveGrandRootSpecialResourceId)) { 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry root; 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.mutable_file_info()->set_is_directory(true); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.set_resource_id(util::kDriveGrandRootSpecialResourceId); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.set_title(util::kDriveGrandRootDirName); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!storage_->PutEntry(CreateEntryWithProperBaseName(root))) 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!storage_->GetEntry(util::kDriveOtherDirSpecialResourceId)) { 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!PutEntryUnderDirectory(util::CreateOtherDirEntry())) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::DestroyOnBlockingPool() { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete this; 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::GetLargestChangestampOnUIThread( 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetChangestampCallback& callback) { 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::GetLargestChangestamp, 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this)), 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::SetLargestChangestampOnUIThread( 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 value, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileOperationCallback& callback) { 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::SetLargestChangestamp, 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value), 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)int64 ResourceMetadata::GetLargestChangestamp() { 268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return storage_->GetLargestChangestamp(); 270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::SetLargestChangestamp(int64 value) { 273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) storage_->SetLargestChangestamp(value); 279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 281b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::AddEntryOnUIThread(const ResourceEntry& entry, 283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const FileMoveCallback& callback) { 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostFileMoveTask(blocking_task_runner_, 288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::AddEntry, 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry), 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::AddEntry(const ResourceEntry& entry, 295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath* out_file_path) { 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> existing_entry = 302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) storage_->GetEntry(entry.resource_id()); 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (existing_entry) 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_EXISTS; 305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> parent = 307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetDirectory(entry.parent_resource_id()); 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!parent) 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!PutEntryUnderDirectory(entry)) 312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_FAILED; 313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_file_path) 315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_file_path = GetFilePath(entry.resource_id()); 316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::MoveEntryToDirectoryOnUIThread( 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path, 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& directory_path, 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileMoveCallback& callback) { 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PostFileMoveTask(blocking_task_runner_, 328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::MoveEntryToDirectory, 329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(this), 330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) file_path, 331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) directory_path), 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::RenameEntryOnUIThread(const base::FilePath& file_path, 336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& new_name, 337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const FileMoveCallback& callback) { 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostFileMoveTask(blocking_task_runner_, 342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::RenameEntry, 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_name), 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::RemoveEntryOnUIThread(const std::string& resource_id, 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const FileMoveCallback& callback) { 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostFileMoveTask(blocking_task_runner_, 355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::RemoveEntry, 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_id), 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::RemoveEntry(const std::string& resource_id, 362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath* out_file_path) { 363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Disallow deletion of special entries "/drive" and "/drive/other". 369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (util::IsSpecialResourceId(resource_id)) 370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_ACCESS_DENIED; 371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!entry) 374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!RemoveEntryRecursively(entry->resource_id())) 377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_FAILED; 378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_file_path) 380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_file_path = GetFilePath(entry->parent_resource_id()); 381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 384a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ResourceMetadata::GetResourceEntryByIdOnUIThread( 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryWithFilePathCallback& callback) { 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* file_path = new base::FilePath; 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry(new ResourceEntry); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry_ptr = entry.get(); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&ResourceMetadata::GetResourceEntryById, 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_id, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_ptr), 401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&RunGetResourceEntryWithFilePathCallback, 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Owned(file_path), 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&entry))); 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)FileError ResourceMetadata::GetResourceEntryById( 408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& resource_id, 409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath* out_file_path, 410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ResourceEntry* out_entry) { 411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(!resource_id.empty()); 413b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!entry) 416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_file_path) 419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_file_path = GetFilePath(resource_id); 420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_entry) 421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_entry = *entry; 422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 426a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ResourceMetadata::GetResourceEntryByPathOnUIThread( 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path, 428a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryCallback& callback) { 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry(new ResourceEntry); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry_ptr = entry.get(); 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 437a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&ResourceMetadata::GetResourceEntryByPath, 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path, 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_ptr), 441a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&RunGetResourceEntryCallback, 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&entry))); 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 446a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path, 447a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ResourceEntry* out_entry) { 448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(out_entry); 450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = FindEntryByPathSync(path); 452b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!entry) 453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_entry = *entry; 456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 458b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 459b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::ReadDirectoryByPathOnUIThread( 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path, 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ReadDirectoryCallback& callback) { 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntryVector> entries(new ResourceEntryVector); 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntryVector* entries_ptr = entries.get(); 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::ReadDirectoryByPath, 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path, 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries_ptr), 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&RunReadDirectoryCallback, 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&entries))); 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::RefreshEntryOnUIThread( 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntry& in_entry, 481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryWithFilePathCallback& callback) { 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* file_path = new base::FilePath; 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry(new ResourceEntry); 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry* entry_ptr = entry.get(); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::RefreshEntry, 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) in_entry, 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path, 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry_ptr), 496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&RunGetResourceEntryWithFilePathCallback, 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Owned(file_path), 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&entry))); 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry, 503b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath* out_file_path, 504b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ResourceEntry* out_entry) { 505b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 506b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 507b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 509b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 510b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> old_entry = 511b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) storage_->GetEntry(entry.resource_id()); 512b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!old_entry) 513b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 514b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 515b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (old_entry->parent_resource_id().empty() || // Rejct root. 516b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) old_entry->file_info().is_directory() != // Reject incompatible input. 517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) entry.file_info().is_directory()) 518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_INVALID_OPERATION; 519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Update data. 521b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> new_parent = 522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetDirectory(entry.parent_resource_id()); 523b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 524b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!new_parent) 525b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 526b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 527b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Remove from the old parent and add it to the new parent with the new data. 528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry))) 529b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_FAILED; 530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_file_path) 532b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_file_path = GetFilePath(entry.resource_id()); 533b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 534b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (out_entry) { 535b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Note that base_name is not the same for the new entry and entry. 536b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> result_entry = 537b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) storage_->GetEntry(entry.resource_id()); 538b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(result_entry); 539b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *out_entry = *result_entry; 540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 541b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 542b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 543b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 544b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::RefreshDirectoryOnUIThread( 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const DirectoryFetchInfo& directory_fetch_info, 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntryMap& entry_map, 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileMoveCallback& callback) { 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PostFileMoveTask(blocking_task_runner_, 552b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::RefreshDirectory, 553b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(this), 554b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) directory_fetch_info, 555b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) entry_map), 556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback); 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ResourceMetadata::GetChildDirectoriesOnUIThread( 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id, 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetChildDirectoriesCallback& changed_dirs_callback) { 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!changed_dirs_callback.is_null()); 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PostTaskAndReplyWithResult( 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_, 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&ResourceMetadata::GetChildDirectories, 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_id), 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&RunGetChildDirectoriesCallbackWithResult, 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) changed_dirs_callback)); 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)scoped_ptr<std::set<base::FilePath> > ResourceMetadata::GetChildDirectories( 575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& resource_id) { 576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<std::set<base::FilePath> > changed_directories( 579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) new std::set<base::FilePath>); 580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (entry && entry->file_info().is_directory()) 582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetDescendantDirectoryPaths(resource_id, changed_directories.get()); 583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return changed_directories.Pass(); 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 587a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() { 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 589b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 590a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return storage_->GetIterator(); 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 593b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)base::FilePath ResourceMetadata::GetFilePath( 594b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& resource_id) { 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath path; 598b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (entry) { 600b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!entry->parent_resource_id().empty()) 601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) path = GetFilePath(entry->parent_resource_id()); 602b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) path = path.Append(base::FilePath::FromUTF8Unsafe(entry->base_name())); 603b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 604b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return path; 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 607b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::MoveEntryToDirectory( 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path, 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& directory_path, 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* out_file_path) { 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_path.empty()); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!file_path.empty()); 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = FindEntryByPathSync(file_path); 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> destination = FindEntryByPathSync(directory_path); 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry || !destination) 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!destination->file_info().is_directory()) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->set_parent_resource_id(destination->resource_id()); 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 627b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return RefreshEntry(*entry, out_file_path, NULL); 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 630b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::RenameEntry( 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path, 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& new_name, 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* out_file_path) { 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!file_path.empty()); 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!new_name.empty()); 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "RenameEntry " << file_path.value() << " to " << new_name; 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = FindEntryByPathSync(file_path); 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::FilePath::FromUTF8Unsafe(new_name) == file_path.BaseName()) 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_EXISTS; 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->set_title(new_name); 651b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return RefreshEntry(*entry, out_file_path, NULL); 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceMetadata::FindEntryByPathSync( 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& file_path) { 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start from the root. 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->GetEntry(util::kDriveGrandRootSpecialResourceId); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(entry); 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(entry->parent_resource_id().empty()); 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check the first component. 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<base::FilePath::StringType> components; 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path.GetComponents(&components); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (components.empty() || 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(components[0]).AsUTF8Unsafe() != entry->base_name()) 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_ptr<ResourceEntry>(); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Iterate over the remaining components. 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 1; i < components.size(); ++i) { 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string component = base::FilePath(components[i]).AsUTF8Unsafe(); 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string resource_id = storage_->GetChild(entry->resource_id(), 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component); 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (resource_id.empty()) 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_ptr<ResourceEntry>(); 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry = storage_->GetEntry(resource_id); 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(entry); 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(entry->base_name(), component); 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return entry.Pass(); 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 686b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::ReadDirectoryByPath( 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& path, 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntryVector* out_entries) { 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(out_entries); 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = FindEntryByPathSync(path); 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry) 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!entry->file_info().is_directory()) 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DirectoryChildrenToProtoVector(entry->resource_id())->swap(*out_entries); 700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_OK; 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 703a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ResourceMetadata::GetResourceEntryPairByPathsOnUIThread( 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& first_path, 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& second_path, 706a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryPairCallback& callback) { 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the first entry. 711a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GetResourceEntryByPathOnUIThread( 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) first_path, 713b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind( 714a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &ResourceMetadata::GetResourceEntryPairByPathsOnUIThreadAfterGetFirst, 715b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 716b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) first_path, 717b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) second_path, 718b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback)); 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 721b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::RefreshDirectory( 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const DirectoryFetchInfo& directory_fetch_info, 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntryMap& entry_map, 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath* out_file_path) { 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!directory_fetch_info.empty()); 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> directory = storage_->GetEntry( 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_fetch_info.resource_id()); 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory) 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_FOUND; 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!directory->file_info().is_directory()) 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory->mutable_directory_specific_info()->set_changestamp( 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_fetch_info.changestamp()); 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->PutEntry(*directory); 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // First, go through the entry map. We'll handle existing entries and new 745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // entries in the loop. We'll process deleted entries afterwards. 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (ResourceEntryMap::const_iterator it = entry_map.begin(); 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it != entry_map.end(); ++it) { 748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntry& entry = it->second; 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Skip if the parent resource ID does not match. This is needed to 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handle entries with multiple parents. For such entries, the first 754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // parent is picked and other parents are ignored, hence some entries may 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // have a parent resource ID which does not match the target directory's. 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(satorux): Move the filtering logic to somewhere more appropriate. 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // crbug.com/193525. 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry.parent_resource_id() != 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directory_fetch_info.resource_id()) { 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "Wrong-parent entry rejected: " << entry.resource_id(); 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry))) 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_FAILED; 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Go through the existing entries and remove deleted entries. 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntryVector> entries = 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DirectoryChildrenToProtoVector(directory->resource_id()); 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < entries->size(); ++i) { 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_NO_SPACE; 775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntry& entry = entries->at(i); 777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_map.count(entry.resource_id()) == 0) { 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!RemoveEntryRecursively(entry.resource_id())) 779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_FAILED; 780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (out_file_path) 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *out_file_path = GetFilePath(directory->resource_id()); 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return FILE_ERROR_OK; 787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceMetadata::GetDirectory( 790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id) { 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!resource_id.empty()); 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return entry && entry->file_info().is_directory() ? 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry.Pass() : scoped_ptr<ResourceEntry>(); 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::GetDescendantDirectoryPaths( 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id, 801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<base::FilePath>* child_directories) { 802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> children; 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->GetChildren(directory_resource_id, &children); 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(children[i]); 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(entry); 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry->file_info().is_directory()) { 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child_directories->insert(GetFilePath(entry->resource_id())); 811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDescendantDirectoryPaths(entry->resource_id(), child_directories); 812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 816a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ResourceMetadata::GetResourceEntryPairByPathsOnUIThreadAfterGetFirst( 817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& first_path, 818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& second_path, 819a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryPairCallback& callback, 820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error, 821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry) { 822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<EntryInfoPairResult> result(new EntryInfoPairResult); 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->first.path = first_path; 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->first.error = error; 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->first.entry = entry.Pass(); 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the first one is not found, don't continue. 831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != FILE_ERROR_OK) { 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(result.Pass()); 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the second entry. 837a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GetResourceEntryByPathOnUIThread( 838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) second_path, 839b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind( 840a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &ResourceMetadata:: 841a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GetResourceEntryPairByPathsOnUIThreadAfterGetSecond, 842b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 843b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) second_path, 844b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback, 845b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Passed(&result))); 846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 848a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ResourceMetadata::GetResourceEntryPairByPathsOnUIThreadAfterGetSecond( 849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& second_path, 850a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GetResourceEntryPairCallback& callback, 851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<EntryInfoPairResult> result, 852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error, 853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry) { 854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!callback.is_null()); 856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(result.get()); 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->second.path = second_path; 859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->second.error = error; 860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->second.entry = entry.Pass(); 861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(result.Pass()); 863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ResourceMetadata::PutEntryUnderDirectory( 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceEntry& entry) { 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry updated_entry(entry); 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry name may have been changed due to prior name de-duplication. 872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We need to first restore the file name based on the title before going 873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // through name de-duplication again when it is added to another directory. 874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetBaseNameFromTitle(&updated_entry); 875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Do file name de-duplication - Keep changing |entry|'s name until there is 877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // no other entry with the same name under the parent. 878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int modifier = 1; 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string new_base_name = updated_entry.base_name(); 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string existing_entry_id = 882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->GetChild(entry.parent_resource_id(), new_base_name); 883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (existing_entry_id.empty() || existing_entry_id == entry.resource_id()) 884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath new_path = 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::FromUTF8Unsafe(updated_entry.base_name()); 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_path = 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_path.InsertBeforeExtension(base::StringPrintf(" (%d)", ++modifier)); 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new_base_name = new_path.AsUTF8Unsafe(); 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) updated_entry.set_base_name(new_base_name); 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add the entry to resource map. 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return storage_->PutEntry(updated_entry); 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ResourceMetadata::RemoveEntryRecursively( 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& resource_id) { 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry = storage_->GetEntry(resource_id); 903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(entry); 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry->file_info().is_directory()) { 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> children; 907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->GetChildren(resource_id, &children); 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!RemoveEntryRecursively(children[i])) 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return storage_->RemoveEntry(resource_id); 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceEntryVector> 917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::DirectoryChildrenToProtoVector( 918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& directory_resource_id) { 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntryVector> entries(new ResourceEntryVector); 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> children; 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) storage_->GetChildren(directory_resource_id, &children); 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> child = storage_->GetEntry(children[i]); 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(child); 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entries->push_back(*child); 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return entries.Pass(); 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace internal 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace drive 934