summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 19:49:52 +0000
committerhshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 19:49:52 +0000
commitb69d0a4aa6ebdc3eff2522f2a9f3cf23831ca7ff (patch)
tree4b6e02e1129f682972175a42e8b7a8ecd10afbb8
parentc82da8c4adce2fcf0fef48442f877f4d5917a6b1 (diff)
downloadchromium_src-b69d0a4aa6ebdc3eff2522f2a9f3cf23831ca7ff.zip
chromium_src-b69d0a4aa6ebdc3eff2522f2a9f3cf23831ca7ff.tar.gz
chromium_src-b69d0a4aa6ebdc3eff2522f2a9f3cf23831ca7ff.tar.bz2
gdata: Get rid of GDataFileSystem::GetFileInfoByPath()
This is part 1 of converting public synchronous functions in GDataFileSystem to asynchronous. Eliminate the helper class GDataFileProperties and the public synchronous function GetFileInfoByPath(). BUG=127048 TEST=unit_tests, browser_tests Review URL: https://chromiumcodereview.appspot.com/10543037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141262 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/extensions/file_handler_util.cc60
-rw-r--r--chrome/browser/chromeos/extensions/file_handler_util.h17
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.cc128
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system.h48
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc35
-rw-r--r--chrome/browser/chromeos/gdata/gdata_file_system_proxy.h9
-rw-r--r--chrome/browser/chromeos/gdata/gdata_util.cc118
-rw-r--r--chrome/browser/chromeos/gdata/gdata_util.h12
-rw-r--r--chrome/browser/chromeos/gdata/mock_gdata_file_system.h2
9 files changed, 269 insertions, 160 deletions
diff --git a/chrome/browser/chromeos/extensions/file_handler_util.cc b/chrome/browser/chromeos/extensions/file_handler_util.cc
index 08db70e..4bbdaa9 100644
--- a/chrome/browser/chromeos/extensions/file_handler_util.cc
+++ b/chrome/browser/chromeos/extensions/file_handler_util.cc
@@ -547,6 +547,14 @@ void FileTaskExecutor::ExecuteFailedOnUIThread() {
Done(false);
}
+const Extension* FileTaskExecutor::GetExtension() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ ExtensionService* service = profile_->GetExtensionService();
+ return service ? service->GetExtensionById(extension_id_, false) :
+ NULL;
+}
+
void FileTaskExecutor::ExecuteFileActionsOnUIThread(
const std::string& file_system_name,
const GURL& file_system_root,
@@ -554,20 +562,37 @@ void FileTaskExecutor::ExecuteFileActionsOnUIThread(
int handler_pid) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- ExtensionService* service = profile_->GetExtensionService();
- if (!service) {
+ const Extension* extension = GetExtension();
+ if (!extension) {
Done(false);
return;
}
- const Extension* extension = service->GetExtensionById(extension_id_, false);
+ InitHandlerHostFileAccessPermissions(
+ file_list,
+ extension,
+ action_id_,
+ base::Bind(&FileTaskExecutor::OnInitAccessForExecuteFileActionsOnUIThread,
+ this,
+ file_system_name,
+ file_system_root,
+ file_list,
+ handler_pid));
+}
+
+void FileTaskExecutor::OnInitAccessForExecuteFileActionsOnUIThread(
+ const std::string& file_system_name,
+ const GURL& file_system_root,
+ const FileDefinitionList& file_list,
+ int handler_pid) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ const Extension* extension = GetExtension();
if (!extension) {
Done(false);
return;
}
- InitHandlerHostFileAccessPermissions(file_list, extension, action_id_);
-
if (handler_pid > 0) {
SetupPermissionsAndDispatchEvent(file_system_name, file_system_root,
file_list, handler_pid, NULL);
@@ -649,9 +674,11 @@ void FileTaskExecutor::SetupPermissionsAndDispatchEvent(
void FileTaskExecutor::InitHandlerHostFileAccessPermissions(
const FileDefinitionList& file_list,
const Extension* handler_extension,
- const std::string& action_id) {
+ const std::string& action_id,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ scoped_ptr<std::vector<FilePath> > gdata_paths(new std::vector<FilePath>);
for (FileDefinitionList::const_iterator iter = file_list.begin();
iter != file_list.end();
++iter) {
@@ -660,15 +687,22 @@ void FileTaskExecutor::InitHandlerHostFileAccessPermissions(
iter->absolute_path,
GetAccessPermissionsForHandler(handler_extension, action_id)));
- if (!gdata::util::IsUnderGDataMountPoint(iter->absolute_path))
- continue;
+ if (gdata::util::IsUnderGDataMountPoint(iter->absolute_path))
+ gdata_paths->push_back(iter->virtual_path);
+ }
- // If the file is on gdata mount point, we'll have to give handler host
- // permissions for file's gdata cache paths.
- // This has to be called on UI thread.
- gdata::util::InsertGDataCachePathsPermissions(profile_, iter->virtual_path,
- &handler_host_permissions_);
+ if (gdata_paths->empty()) {
+ // Invoke callback if none of the files are on gdata mount point.
+ callback.Run();
+ return;
}
+
+ // For files on gdata mount point, we'll have to give handler host permissions
+ // for their cache paths. This has to be called on UI thread.
+ gdata::util::InsertGDataCachePathsPermissions(profile_,
+ gdata_paths.Pass(),
+ &handler_host_permissions_,
+ callback);
}
void FileTaskExecutor::SetupHandlerHostFileAccessPermissions(int handler_pid) {
diff --git a/chrome/browser/chromeos/extensions/file_handler_util.h b/chrome/browser/chromeos/extensions/file_handler_util.h
index 84b0e2f..144fa94 100644
--- a/chrome/browser/chromeos/extensions/file_handler_util.h
+++ b/chrome/browser/chromeos/extensions/file_handler_util.h
@@ -109,7 +109,7 @@ class FileTaskExecutor : public base::RefCountedThreadSafe<FileTaskExecutor> {
void ExecuteFileActionsOnUIThread(const std::string& file_system_name,
const GURL& file_system_root,
const FileDefinitionList& file_list,
- int handler_id);
+ int handler_pid);
void SetupPermissionsAndDispatchEvent(const std::string& file_system_name,
const GURL& file_system_root,
const FileDefinitionList& file_list,
@@ -121,11 +121,24 @@ class FileTaskExecutor : public base::RefCountedThreadSafe<FileTaskExecutor> {
void InitHandlerHostFileAccessPermissions(
const FileDefinitionList& file_list,
const extensions::Extension* handler_extension,
- const std::string& action_id);
+ const std::string& action_id,
+ const base::Closure& callback);
+
+ // Invoked upon completion of InitHandlerHostFileAccessPermissions initiated
+ // by ExecuteFileActionsOnUIThread.
+ void OnInitAccessForExecuteFileActionsOnUIThread(
+ const std::string& file_system_name,
+ const GURL& file_system_root,
+ const FileDefinitionList& file_list,
+ int handler_pid);
+
// Registers file permissions from |handler_host_permissions_| with
// ChildProcessSecurityPolicy for process with id |handler_pid|.
void SetupHandlerHostFileAccessPermissions(int handler_pid);
+ // Helper function to get the extension pointer.
+ const extensions::Extension* GetExtension();
+
Profile* profile_;
const GURL source_url_;
const std::string extension_id_;
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.cc b/chrome/browser/chromeos/gdata/gdata_file_system.cc
index bc9de4a..c73dd2e 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.cc
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.cc
@@ -837,14 +837,6 @@ CallbackType CreateRelayCallback(const CallbackType& callback) {
} // namespace
-// GDataFileProperties struct implementation.
-
-GDataFileProperties::GDataFileProperties() : is_hosted_document(false) {
-}
-
-GDataFileProperties::~GDataFileProperties() {
-}
-
// GDataFileSystem::GetDocumentsParams struct implementation.
GDataFileSystem::GetDocumentsParams::GetDocumentsParams(
@@ -1976,8 +1968,40 @@ void GDataFileSystem::GetFileByPathOnUIThread(
const GetDownloadDataCallback& get_download_data_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- GDataFileProperties file_properties;
- if (!GetFileInfoByPath(file_path, &file_properties)) {
+ GetFileInfoByPathAsync(
+ file_path,
+ base::Bind(&GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath,
+ ui_weak_ptr_,
+ file_path,
+ CreateRelayCallback(get_file_callback),
+ CreateRelayCallback(get_download_data_callback)));
+}
+
+void GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath(
+ const FilePath& file_path,
+ const GetFileCallback& get_file_callback,
+ const GetDownloadDataCallback& get_download_data_callback,
+ base::PlatformFileError error,
+ scoped_ptr<GDataFileProto> file_info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ DCHECK(!file_info->gdata_entry().resource_id().empty());
+ GetResolvedFileByPath(file_path,
+ get_file_callback,
+ get_download_data_callback,
+ error,
+ file_info.get());
+}
+
+void GDataFileSystem::GetResolvedFileByPath(
+ const FilePath& file_path,
+ const GetFileCallback& get_file_callback,
+ const GetDownloadDataCallback& get_download_data_callback,
+ base::PlatformFileError error,
+ const GDataFileProto* file_proto) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (error != base::PLATFORM_FILE_OK || !file_proto) {
if (!get_file_callback.is_null()) {
MessageLoop::current()->PostTask(
FROM_HERE,
@@ -1994,7 +2018,7 @@ void GDataFileSystem::GetFileByPathOnUIThread(
// document instead of fetching the document content in one of the exported
// formats. The JSON file contains the edit URL and resource ID of the
// document.
- if (file_properties.is_hosted_document) {
+ if (file_proto->is_hosted_document()) {
base::PlatformFileError* error =
new base::PlatformFileError(base::PLATFORM_FILE_OK);
FilePath* temp_file_path = new FilePath;
@@ -2005,8 +2029,8 @@ void GDataFileSystem::GetFileByPathOnUIThread(
base::Bind(&CreateDocumentJsonFileOnBlockingPool,
GetCacheDirectoryPath(
GDataCache::CACHE_TYPE_TMP_DOCUMENTS),
- file_properties.alternate_url,
- file_properties.resource_id,
+ GURL(file_proto->alternate_url()),
+ file_proto->gdata_entry().resource_id(),
error,
temp_file_path,
mime_type,
@@ -2022,22 +2046,22 @@ void GDataFileSystem::GetFileByPathOnUIThread(
// Returns absolute path of the file if it were cached or to be cached.
FilePath local_tmp_path = cache_->GetCacheFilePath(
- file_properties.resource_id,
- file_properties.file_md5,
+ file_proto->gdata_entry().resource_id(),
+ file_proto->file_md5(),
GDataCache::CACHE_TYPE_TMP,
GDataCache::CACHED_FILE_FROM_SERVER);
GetFileFromCacheByResourceIdAndMd5(
- file_properties.resource_id,
- file_properties.file_md5,
+ file_proto->gdata_entry().resource_id(),
+ file_proto->file_md5(),
base::Bind(
&GDataFileSystem::OnGetFileFromCache,
ui_weak_ptr_,
GetFileFromCacheParams(file_path,
local_tmp_path,
- file_properties.content_url,
- file_properties.resource_id,
- file_properties.file_md5,
- file_properties.mime_type,
+ GURL(file_proto->gdata_entry().content_url()),
+ file_proto->gdata_entry().resource_id(),
+ file_proto->file_md5(),
+ file_proto->content_mime_type(),
get_file_callback,
get_download_data_callback)));
}
@@ -2483,28 +2507,6 @@ void GDataFileSystem::OnRequestDirectoryRefresh(
DVLOG(1) << "Directory refreshed: " << directory_path.value();
}
-bool GDataFileSystem::GetFileInfoByPath(
- const FilePath& file_path, GDataFileProperties* properties) {
- DCHECK(properties);
- base::AutoLock lock(lock_);
- GDataEntry* entry = GetGDataEntryByPath(file_path);
- if (!entry)
- return false;
-
- properties->file_info = entry->file_info();
- properties->resource_id = entry->resource_id();
-
- GDataFile* regular_file = entry->AsGDataFile();
- if (regular_file) {
- properties->file_md5 = regular_file->file_md5();
- properties->mime_type = regular_file->content_mime_type();
- properties->content_url = regular_file->content_url();
- properties->alternate_url = regular_file->alternate_url();
- properties->is_hosted_document = regular_file->is_hosted_document();
- }
- return true;
-}
-
GDataEntry* GDataFileSystem::GetGDataEntryByPath(
const FilePath& file_path) {
lock_.AssertAcquired();
@@ -5078,21 +5080,15 @@ void GDataFileSystem::OnGetFileInfoCompleteForOpenFile(
}
DCHECK(!file_info->gdata_entry().resource_id().empty());
-
- // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection.
- // Do not call GetFileByPathOnUIThread() directly for avoiding deadlock.
- // The current method is called as a callback from GetFileInfoByPathAsync(),
- // which is under the lock taken.
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(&GDataFileSystem::GetFileByPathOnUIThread,
+ GetResolvedFileByPath(
+ file_path,
+ base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile,
ui_weak_ptr_,
- file_path,
- base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile,
- ui_weak_ptr_,
- callback,
- base::Passed(&file_info)),
- GetDownloadDataCallback()));
+ callback,
+ base::Passed(&file_info)),
+ GetDownloadDataCallback(),
+ error,
+ file_info.get());
}
void GDataFileSystem::OnGetFileCompleteForOpenFile(
@@ -5181,21 +5177,13 @@ void GDataFileSystem::OnGetFileInfoCompleteForCloseFile(
// if the file has not been modified. Come up with a way to detect the
// intactness effectively, or provide a method for user to declare it when
// calling CloseFile().
-
- // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection.
- // Do not call CommitDirtyInCache() directly for avoiding deadlock.
- // The current method is called as a callback from GetFileInfoByPathAsync(),
- // which is under the lock taken.
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE,
+ CommitDirtyInCache(
+ file_info->gdata_entry().resource_id(),
+ file_info->file_md5(),
base::Bind(
- &GDataFileSystem::CommitDirtyInCache,
+ &GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile,
ui_weak_ptr_,
- file_info->gdata_entry().resource_id(),
- file_info->file_md5(),
- base::Bind(&GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile,
- ui_weak_ptr_,
- callback)));
+ callback));
}
void GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile(
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.h b/chrome/browser/chromeos/gdata/gdata_file_system.h
index f0a6f89..b8daad4 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system.h
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.h
@@ -114,21 +114,6 @@ typedef base::Callback<void(const std::string& resource_id)>
typedef base::Callback<void(base::PlatformFileError error,
int cache_state)> GetCacheStateCallback;
-// Helper structure used for extracting key properties from GDataFile object.
-// TODO(satorux): Remove this as part of crosbug.com/30066
-struct GDataFileProperties {
- GDataFileProperties();
- ~GDataFileProperties();
-
- base::PlatformFileInfo file_info;
- std::string resource_id;
- std::string file_md5;
- std::string mime_type;
- GURL content_url;
- GURL alternate_url;
- bool is_hosted_document;
-};
-
// GData file system abstraction layer.
// The interface is defined to make GDataFileSystem mockable.
class GDataFileSystemInterface {
@@ -392,13 +377,6 @@ class GDataFileSystemInterface {
virtual void SearchAsync(const std::string& search_query,
const ReadDirectoryCallback& callback) = 0;
-
- // Finds a file (not a directory) by |file_path| and returns its key
- // |properties|. Returns true if file was found.
- // TODO(satorux): Remove this: crosbug.com/30066.
- virtual bool GetFileInfoByPath(const FilePath& file_path,
- GDataFileProperties* properties) = 0;
-
// Returns true if the given path is under gdata cache directory, i.e.
// <user_profile_dir>/GCache/v1
virtual bool IsUnderGDataCacheDirectory(const FilePath& path) const = 0;
@@ -508,8 +486,6 @@ class GDataFileSystem : public GDataFileSystemInterface,
const ReadDirectoryCallback& callback) OVERRIDE;
virtual void RequestDirectoryRefresh(
const FilePath& file_path) OVERRIDE;
- virtual bool GetFileInfoByPath(const FilePath& file_path,
- GDataFileProperties* properties) OVERRIDE;
virtual bool IsUnderGDataCacheDirectory(const FilePath& path) const OVERRIDE;
virtual FilePath GetCacheDirectoryPath(
GDataCache::CacheSubDirectoryType sub_dir_type) const OVERRIDE;
@@ -692,16 +668,24 @@ class GDataFileSystem : public GDataFileSystemInterface,
const FilePath& remote_dest_file_path,
const FileOperationCallback& callback);
+ // Invoked upon completion of GetFileInfoByPathAsync initiated by
+ // GetFileByPath. It then continues to invoke GetResolvedFileByPath.
+ void OnGetFileInfoCompleteForGetFileByPath(
+ const FilePath& file_path,
+ const GetFileCallback& get_file_callback,
+ const GetDownloadDataCallback& get_download_data_callback,
+ base::PlatformFileError error,
+ scoped_ptr<GDataFileProto> file_info);
// Invoked upon completion of GetFileInfoByPathAsync initiated by OpenFile.
- // It then continues to invoke GetFileByPath and processed to
+ // It then continues to invoke GetResolvedFileByPath and proceeds to
// OnGetFileCompleteForOpenFile.
void OnGetFileInfoCompleteForOpenFile(const FilePath& file_path,
const OpenFileCallback& callback,
base::PlatformFileError error,
scoped_ptr<GDataFileProto> file_info);
// Invoked upon completion of GetFileInfoByPathAsync initiated by CloseFile.
- // It then continues to invoke GetFileByPath and processed to
- // OnGetFileCompleteForCloseFile.
+ // It then continues to invoke CommitDirtyInCache and proceeds to
+ // OnCommitDirtyInCacheCompleteForCloseFile.
void OnGetFileInfoCompleteForCloseFile(const FilePath& file_path,
const CloseFileCallback& callback,
base::PlatformFileError error,
@@ -1419,6 +1403,16 @@ class GDataFileSystem : public GDataFileSystemInterface,
void FindEntryByPathAsyncOnUIThread(const FilePath& search_file_path,
const FindEntryCallback& callback);
+ // Gets |file_path| from the file system after the file info is already
+ // resolved with GetFileInfoByPathAsync(). This function is called by
+ // OnGetFileInfoCompleteForGetFileByPath and OnGetFileInfoCompleteForOpenFile.
+ void GetResolvedFileByPath(
+ const FilePath& file_path,
+ const GetFileCallback& get_file_callback,
+ const GetDownloadDataCallback& get_download_data_callback,
+ base::PlatformFileError error,
+ const GDataFileProto* file_proto);
+
// The following functions are used to forward calls to asynchronous public
// member functions to UI thread.
void SearchAsyncOnUIThread(const std::string& search_query,
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc
index decfef4..ec35486 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc
+++ b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc
@@ -215,10 +215,7 @@ void GDataFileSystemProxy::CreateSnapshotFile(
const GURL& file_url,
const FileSystemOperationInterface::SnapshotFileCallback& callback) {
FilePath file_path;
- base::PlatformFileInfo file_info;
- GDataFileProperties file_properties;
- if (!ValidateUrl(file_url, &file_path) ||
- !file_system_->GetFileInfoByPath(file_path, &file_properties)) {
+ if (!ValidateUrl(file_url, &file_path)) {
MessageLoopProxy::current()->PostTask(FROM_HERE,
base::Bind(callback,
base::PLATFORM_FILE_ERROR_NOT_FOUND,
@@ -228,10 +225,36 @@ void GDataFileSystemProxy::CreateSnapshotFile(
return;
}
- file_system_->GetFileByPath(file_path,
+ file_system_->GetEntryInfoByPathAsync(
+ file_path,
+ base::Bind(&GDataFileSystemProxy::OnGetEntryInfoByPathAsync,
+ this, callback));
+}
+
+void GDataFileSystemProxy::OnGetEntryInfoByPathAsync(
+ const FileSystemOperationInterface::SnapshotFileCallback& callback,
+ base::PlatformFileError error,
+ const FilePath& entry_path,
+ scoped_ptr<GDataEntryProto> entry_proto) {
+ if (error != base::PLATFORM_FILE_OK || !entry_proto.get()) {
+ MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(callback,
+ base::PLATFORM_FILE_ERROR_NOT_FOUND,
+ base::PlatformFileInfo(),
+ FilePath(),
+ scoped_refptr<ShareableFileReference>(NULL)));
+ return;
+ }
+
+ base::PlatformFileInfo file_info;
+ GDataEntry::ConvertProtoToPlatformFileInfo(
+ entry_proto->file_info(),
+ &file_info);
+
+ file_system_->GetFileByPath(entry_path,
base::Bind(&CallSnapshotFileCallback,
callback,
- file_properties.file_info),
+ file_info),
GetDownloadDataCallback());
}
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.h b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.h
index d510102..4d5595f 100644
--- a/chrome/browser/chromeos/gdata/gdata_file_system_proxy.h
+++ b/chrome/browser/chromeos/gdata/gdata_file_system_proxy.h
@@ -69,6 +69,15 @@ class GDataFileSystemProxy : public fileapi::RemoteFileSystemProxyInterface {
const FilePath& entry_path,
scoped_ptr<gdata::GDataEntryProto> entry_proto);
+ // Helper callback for relaying reply for GetEntryInfoByPathAsync() to the
+ // calling thread.
+ void OnGetEntryInfoByPathAsync(
+ const fileapi::FileSystemOperationInterface::SnapshotFileCallback&
+ callback,
+ base::PlatformFileError error,
+ const FilePath& entry_path,
+ scoped_ptr<GDataEntryProto> entry_proto);
+
// Helper callback for relaying reply for ReadDirectory() to the calling
// thread.
void OnReadDirectory(
diff --git a/chrome/browser/chromeos/gdata/gdata_util.cc b/chrome/browser/chromeos/gdata/gdata_util.cc
index a4635ac..722441a 100644
--- a/chrome/browser/chromeos/gdata/gdata_util.cc
+++ b/chrome/browser/chromeos/gdata/gdata_util.cc
@@ -21,6 +21,7 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "chrome/browser/chromeos/gdata/gdata.pb.h"
#include "chrome/browser/chromeos/gdata/gdata_file_system.h"
#include "chrome/browser/chromeos/gdata/gdata_system_service.h"
#include "chrome/browser/chromeos/login/user.h"
@@ -93,6 +94,58 @@ void OpenEditURLUIThread(Profile* profile, GURL* edit_url) {
}
}
+// Invoked upon completion of GetFileInfoByPathAsync initiated by
+// InsertGDataCachePathPermissions.
+void OnGetFileInfoForInsertGDataCachePathsPermissions(
+ Profile* profile,
+ std::vector<std::pair<FilePath, int> >* cache_paths,
+ const base::Closure& callback,
+ base::PlatformFileError error,
+ scoped_ptr<GDataFileProto> file_info) {
+ DCHECK(profile);
+ DCHECK(cache_paths);
+ DCHECK(!callback.is_null());
+
+ GDataFileSystem* file_system = GetGDataFileSystem(profile);
+ if (!file_system || error != base::PLATFORM_FILE_OK) {
+ callback.Run();
+ return;
+ }
+
+ DCHECK(file_info.get());
+ std::string resource_id = file_info->gdata_entry().resource_id();
+ std::string file_md5 = file_info->file_md5();
+
+ // We check permissions for raw cache file paths only for read-only
+ // operations (when fileEntry.file() is called), so read only permissions
+ // should be sufficient for all cache paths. For the rest of supported
+ // operations the file access check is done for drive/ paths.
+ cache_paths->push_back(std::make_pair(
+ file_system->GetCacheFilePath(resource_id, file_md5,
+ GDataCache::CACHE_TYPE_PERSISTENT,
+ GDataCache::CACHED_FILE_FROM_SERVER),
+ kReadOnlyFilePermissions));
+ // TODO(tbarzic): When we start supporting openFile operation, we may have to
+ // change permission for localy modified files to match handler's permissions.
+ cache_paths->push_back(std::make_pair(
+ file_system->GetCacheFilePath(resource_id, file_md5,
+ GDataCache::CACHE_TYPE_PERSISTENT,
+ GDataCache::CACHED_FILE_LOCALLY_MODIFIED),
+ kReadOnlyFilePermissions));
+ cache_paths->push_back(std::make_pair(
+ file_system->GetCacheFilePath(resource_id, file_md5,
+ GDataCache::CACHE_TYPE_PERSISTENT,
+ GDataCache::CACHED_FILE_MOUNTED),
+ kReadOnlyFilePermissions));
+ cache_paths->push_back(std::make_pair(
+ file_system->GetCacheFilePath(resource_id, file_md5,
+ GDataCache::CACHE_TYPE_TMP,
+ GDataCache::CACHED_FILE_FROM_SERVER),
+ kReadOnlyFilePermissions));
+
+ callback.Run();
+}
+
} // namespace
const FilePath& GetGDataMountPointPath() {
@@ -231,47 +284,40 @@ FilePath ExtractGDataPath(const FilePath& path) {
void InsertGDataCachePathsPermissions(
Profile* profile,
- const FilePath& gdata_path,
- std::vector<std::pair<FilePath, int> >* cache_paths ) {
+ scoped_ptr<std::vector<FilePath> > gdata_paths,
+ std::vector<std::pair<FilePath, int> >* cache_paths,
+ const base::Closure& callback) {
+ DCHECK(profile);
+ DCHECK(gdata_paths.get());
DCHECK(cache_paths);
+ DCHECK(!callback.is_null());
GDataFileSystem* file_system = GetGDataFileSystem(profile);
- if (!file_system)
+ if (!file_system || gdata_paths->empty()) {
+ callback.Run();
return;
+ }
- GDataFileProperties file_properties;
- if (!file_system->GetFileInfoByPath(gdata_path, &file_properties))
- return;
-
- std::string resource_id = file_properties.resource_id;
- std::string file_md5 = file_properties.file_md5;
-
- // We check permissions for raw cache file paths only for read-only
- // operations (when fileEntry.file() is called), so read only permissions
- // should be sufficient for all cache paths. For the rest of supported
- // operations the file access check is done for drive/ paths.
- cache_paths->push_back(std::make_pair(
- file_system->GetCacheFilePath(resource_id, file_md5,
- GDataCache::CACHE_TYPE_PERSISTENT,
- GDataCache::CACHED_FILE_FROM_SERVER),
- kReadOnlyFilePermissions));
- // TODO(tbarzic): When we start supporting openFile operation, we may have to
- // change permission for localy modified files to match handler's permissions.
- cache_paths->push_back(std::make_pair(
- file_system->GetCacheFilePath(resource_id, file_md5,
- GDataCache::CACHE_TYPE_PERSISTENT,
- GDataCache::CACHED_FILE_LOCALLY_MODIFIED),
- kReadOnlyFilePermissions));
- cache_paths->push_back(std::make_pair(
- file_system->GetCacheFilePath(resource_id, file_md5,
- GDataCache::CACHE_TYPE_PERSISTENT,
- GDataCache::CACHED_FILE_MOUNTED),
- kReadOnlyFilePermissions));
- cache_paths->push_back(std::make_pair(
- file_system->GetCacheFilePath(resource_id, file_md5,
- GDataCache::CACHE_TYPE_TMP,
- GDataCache::CACHED_FILE_FROM_SERVER),
- kReadOnlyFilePermissions));
+ // Remove one file path entry from the back of the input vector |gdata_paths|.
+ FilePath gdata_path = gdata_paths->back();
+ gdata_paths->pop_back();
+
+ // Call GetFileInfoByPathAsync() to get file info for |gdata_path| then insert
+ // all possible cache paths to the output vector |cache_paths|.
+ // Note that we can only process one file path at a time. Upon completion
+ // of OnGetFileInfoForInsertGDataCachePathsPermissions(), we recursively call
+ // InsertGDataCachePathsPermissions() to process the next file path from the
+ // back of the input vector |gdata_paths| until it is empty.
+ file_system->GetFileInfoByPathAsync(
+ gdata_path,
+ base::Bind(&OnGetFileInfoForInsertGDataCachePathsPermissions,
+ profile,
+ cache_paths,
+ base::Bind(&InsertGDataCachePathsPermissions,
+ profile,
+ base::Passed(&gdata_paths),
+ cache_paths,
+ callback)));
}
bool IsGDataAvailable(Profile* profile) {
diff --git a/chrome/browser/chromeos/gdata/gdata_util.h b/chrome/browser/chromeos/gdata/gdata_util.h
index 87a6c25..7da949e 100644
--- a/chrome/browser/chromeos/gdata/gdata_util.h
+++ b/chrome/browser/chromeos/gdata/gdata_util.h
@@ -9,6 +9,8 @@
#include <string>
#include <vector>
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
#include "googleurl/src/gurl.h"
class FilePath;
@@ -77,12 +79,14 @@ bool ParseSearchFileName(const std::string& search_file_name,
// Examples: ExtractGDatPath("/special/drive/foo.txt") => "drive/foo.txt"
FilePath ExtractGDataPath(const FilePath& path);
-// Returns vector of all possible cache paths for a given path on gdata mount
-// point.
+// Inserts all possible cache paths for a given vector of paths on gdata mount
+// point into the output vector |cache_paths|, and then invokes callback.
+// Caller must ensure that |cache_paths| lives until the callback is invoked.
void InsertGDataCachePathsPermissions(
Profile* profile_,
- const FilePath& gdata_path,
- std::vector<std::pair<FilePath, int> >* cache_paths);
+ scoped_ptr<std::vector<FilePath> > gdata_paths,
+ std::vector<std::pair<FilePath, int> >* cache_paths,
+ const base::Closure& callback);
// Returns true if gdata is currently active with the specified profile.
bool IsGDataAvailable(Profile* profile);
diff --git a/chrome/browser/chromeos/gdata/mock_gdata_file_system.h b/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
index f0a2a92..20acce3 100644
--- a/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
+++ b/chrome/browser/chromeos/gdata/mock_gdata_file_system.h
@@ -80,8 +80,6 @@ class MockGDataFileSystem : public GDataFileSystemInterface {
const ReadDirectoryCallback& callback));
MOCK_METHOD1(RequestDirectoryRefresh,
void(const FilePath& file_path));
- MOCK_METHOD2(GetFileInfoByPath, bool(const FilePath& file_path,
- GDataFileProperties* properties));
MOCK_CONST_METHOD1(IsUnderGDataCacheDirectory, bool(const FilePath& path));
MOCK_CONST_METHOD1(GetCacheDirectoryPath, FilePath(
GDataCache::CacheSubDirectoryType));