| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| (...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 // Returns callback which runs the given |callback| on the current thread. | 830 // Returns callback which runs the given |callback| on the current thread. |
| 831 template<typename CallbackType> | 831 template<typename CallbackType> |
| 832 CallbackType CreateRelayCallback(const CallbackType& callback) { | 832 CallbackType CreateRelayCallback(const CallbackType& callback) { |
| 833 return base::Bind(&RelayCallback<CallbackType>::Run, | 833 return base::Bind(&RelayCallback<CallbackType>::Run, |
| 834 base::MessageLoopProxy::current(), | 834 base::MessageLoopProxy::current(), |
| 835 callback); | 835 callback); |
| 836 } | 836 } |
| 837 | 837 |
| 838 } // namespace | 838 } // namespace |
| 839 | 839 |
| 840 // GDataFileProperties struct implementation. | |
| 841 | |
| 842 GDataFileProperties::GDataFileProperties() : is_hosted_document(false) { | |
| 843 } | |
| 844 | |
| 845 GDataFileProperties::~GDataFileProperties() { | |
| 846 } | |
| 847 | |
| 848 // GDataFileSystem::GetDocumentsParams struct implementation. | 840 // GDataFileSystem::GetDocumentsParams struct implementation. |
| 849 | 841 |
| 850 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( | 842 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
| 851 int start_changestamp, | 843 int start_changestamp, |
| 852 int root_feed_changestamp, | 844 int root_feed_changestamp, |
| 853 std::vector<DocumentFeed*>* feed_list, | 845 std::vector<DocumentFeed*>* feed_list, |
| 854 bool should_fetch_multiple_feeds, | 846 bool should_fetch_multiple_feeds, |
| 855 const FilePath& search_file_path, | 847 const FilePath& search_file_path, |
| 856 const std::string& search_query, | 848 const std::string& search_query, |
| 857 const std::string& directory_resource_id, | 849 const std::string& directory_resource_id, |
| (...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1969 CreateRelayCallback(get_file_callback), | 1961 CreateRelayCallback(get_file_callback), |
| 1970 CreateRelayCallback(get_download_data_callback))); | 1962 CreateRelayCallback(get_download_data_callback))); |
| 1971 } | 1963 } |
| 1972 | 1964 |
| 1973 void GDataFileSystem::GetFileByPathOnUIThread( | 1965 void GDataFileSystem::GetFileByPathOnUIThread( |
| 1974 const FilePath& file_path, | 1966 const FilePath& file_path, |
| 1975 const GetFileCallback& get_file_callback, | 1967 const GetFileCallback& get_file_callback, |
| 1976 const GetDownloadDataCallback& get_download_data_callback) { | 1968 const GetDownloadDataCallback& get_download_data_callback) { |
| 1977 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1978 | 1970 |
| 1979 GDataFileProperties file_properties; | 1971 GetFileInfoByPathAsync( |
| 1980 if (!GetFileInfoByPath(file_path, &file_properties)) { | 1972 file_path, |
| 1973 base::Bind(&GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath, |
| 1974 ui_weak_ptr_, |
| 1975 file_path, |
| 1976 CreateRelayCallback(get_file_callback), |
| 1977 CreateRelayCallback(get_download_data_callback))); |
| 1978 } |
| 1979 |
| 1980 void GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath( |
| 1981 const FilePath& file_path, |
| 1982 const GetFileCallback& get_file_callback, |
| 1983 const GetDownloadDataCallback& get_download_data_callback, |
| 1984 base::PlatformFileError error, |
| 1985 scoped_ptr<GDataFileProto> file_info) { |
| 1986 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1987 |
| 1988 DCHECK(!file_info->gdata_entry().resource_id().empty()); |
| 1989 GetResolvedFileByPath(file_path, |
| 1990 get_file_callback, |
| 1991 get_download_data_callback, |
| 1992 error, |
| 1993 file_info.get()); |
| 1994 } |
| 1995 |
| 1996 void GDataFileSystem::GetResolvedFileByPath( |
| 1997 const FilePath& file_path, |
| 1998 const GetFileCallback& get_file_callback, |
| 1999 const GetDownloadDataCallback& get_download_data_callback, |
| 2000 base::PlatformFileError error, |
| 2001 const GDataFileProto* file_proto) { |
| 2002 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2003 |
| 2004 if (error != base::PLATFORM_FILE_OK || !file_proto) { |
| 1981 if (!get_file_callback.is_null()) { | 2005 if (!get_file_callback.is_null()) { |
| 1982 MessageLoop::current()->PostTask( | 2006 MessageLoop::current()->PostTask( |
| 1983 FROM_HERE, | 2007 FROM_HERE, |
| 1984 base::Bind(get_file_callback, | 2008 base::Bind(get_file_callback, |
| 1985 base::PLATFORM_FILE_ERROR_NOT_FOUND, | 2009 base::PLATFORM_FILE_ERROR_NOT_FOUND, |
| 1986 FilePath(), | 2010 FilePath(), |
| 1987 std::string(), | 2011 std::string(), |
| 1988 REGULAR_FILE)); | 2012 REGULAR_FILE)); |
| 1989 } | 2013 } |
| 1990 return; | 2014 return; |
| 1991 } | 2015 } |
| 1992 | 2016 |
| 1993 // For a hosted document, we create a special JSON file to represent the | 2017 // For a hosted document, we create a special JSON file to represent the |
| 1994 // document instead of fetching the document content in one of the exported | 2018 // document instead of fetching the document content in one of the exported |
| 1995 // formats. The JSON file contains the edit URL and resource ID of the | 2019 // formats. The JSON file contains the edit URL and resource ID of the |
| 1996 // document. | 2020 // document. |
| 1997 if (file_properties.is_hosted_document) { | 2021 if (file_proto->is_hosted_document()) { |
| 1998 base::PlatformFileError* error = | 2022 base::PlatformFileError* error = |
| 1999 new base::PlatformFileError(base::PLATFORM_FILE_OK); | 2023 new base::PlatformFileError(base::PLATFORM_FILE_OK); |
| 2000 FilePath* temp_file_path = new FilePath; | 2024 FilePath* temp_file_path = new FilePath; |
| 2001 std::string* mime_type = new std::string; | 2025 std::string* mime_type = new std::string; |
| 2002 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); | 2026 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); |
| 2003 PostBlockingPoolSequencedTaskAndReply( | 2027 PostBlockingPoolSequencedTaskAndReply( |
| 2004 FROM_HERE, | 2028 FROM_HERE, |
| 2005 base::Bind(&CreateDocumentJsonFileOnBlockingPool, | 2029 base::Bind(&CreateDocumentJsonFileOnBlockingPool, |
| 2006 GetCacheDirectoryPath( | 2030 GetCacheDirectoryPath( |
| 2007 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), | 2031 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), |
| 2008 file_properties.alternate_url, | 2032 GURL(file_proto->alternate_url()), |
| 2009 file_properties.resource_id, | 2033 file_proto->gdata_entry().resource_id(), |
| 2010 error, | 2034 error, |
| 2011 temp_file_path, | 2035 temp_file_path, |
| 2012 mime_type, | 2036 mime_type, |
| 2013 file_type), | 2037 file_type), |
| 2014 base::Bind(&RunGetFileCallbackHelper, | 2038 base::Bind(&RunGetFileCallbackHelper, |
| 2015 get_file_callback, | 2039 get_file_callback, |
| 2016 base::Owned(error), | 2040 base::Owned(error), |
| 2017 base::Owned(temp_file_path), | 2041 base::Owned(temp_file_path), |
| 2018 base::Owned(mime_type), | 2042 base::Owned(mime_type), |
| 2019 base::Owned(file_type))); | 2043 base::Owned(file_type))); |
| 2020 return; | 2044 return; |
| 2021 } | 2045 } |
| 2022 | 2046 |
| 2023 // Returns absolute path of the file if it were cached or to be cached. | 2047 // Returns absolute path of the file if it were cached or to be cached. |
| 2024 FilePath local_tmp_path = cache_->GetCacheFilePath( | 2048 FilePath local_tmp_path = cache_->GetCacheFilePath( |
| 2025 file_properties.resource_id, | 2049 file_proto->gdata_entry().resource_id(), |
| 2026 file_properties.file_md5, | 2050 file_proto->file_md5(), |
| 2027 GDataCache::CACHE_TYPE_TMP, | 2051 GDataCache::CACHE_TYPE_TMP, |
| 2028 GDataCache::CACHED_FILE_FROM_SERVER); | 2052 GDataCache::CACHED_FILE_FROM_SERVER); |
| 2029 GetFileFromCacheByResourceIdAndMd5( | 2053 GetFileFromCacheByResourceIdAndMd5( |
| 2030 file_properties.resource_id, | 2054 file_proto->gdata_entry().resource_id(), |
| 2031 file_properties.file_md5, | 2055 file_proto->file_md5(), |
| 2032 base::Bind( | 2056 base::Bind( |
| 2033 &GDataFileSystem::OnGetFileFromCache, | 2057 &GDataFileSystem::OnGetFileFromCache, |
| 2034 ui_weak_ptr_, | 2058 ui_weak_ptr_, |
| 2035 GetFileFromCacheParams(file_path, | 2059 GetFileFromCacheParams(file_path, |
| 2036 local_tmp_path, | 2060 local_tmp_path, |
| 2037 file_properties.content_url, | 2061 GURL(file_proto->gdata_entry().content_url()), |
| 2038 file_properties.resource_id, | 2062 file_proto->gdata_entry().resource_id(), |
| 2039 file_properties.file_md5, | 2063 file_proto->file_md5(), |
| 2040 file_properties.mime_type, | 2064 file_proto->content_mime_type(), |
| 2041 get_file_callback, | 2065 get_file_callback, |
| 2042 get_download_data_callback))); | 2066 get_download_data_callback))); |
| 2043 } | 2067 } |
| 2044 | 2068 |
| 2045 void GDataFileSystem::GetFileByResourceId( | 2069 void GDataFileSystem::GetFileByResourceId( |
| 2046 const std::string& resource_id, | 2070 const std::string& resource_id, |
| 2047 const GetFileCallback& get_file_callback, | 2071 const GetFileCallback& get_file_callback, |
| 2048 const GetDownloadDataCallback& get_download_data_callback) { | 2072 const GetDownloadDataCallback& get_download_data_callback) { |
| 2049 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2073 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 2050 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2074 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 directory->AddEntry(entry.release()); | 2500 directory->AddEntry(entry.release()); |
| 2477 } | 2501 } |
| 2478 | 2502 |
| 2479 // Note that there may be no change in the directory, but it's expensive to | 2503 // Note that there may be no change in the directory, but it's expensive to |
| 2480 // check if the new metadata matches the existing one, so we just always | 2504 // check if the new metadata matches the existing one, so we just always |
| 2481 // notify that the directory is changed. | 2505 // notify that the directory is changed. |
| 2482 NotifyDirectoryChanged(directory_path); | 2506 NotifyDirectoryChanged(directory_path); |
| 2483 DVLOG(1) << "Directory refreshed: " << directory_path.value(); | 2507 DVLOG(1) << "Directory refreshed: " << directory_path.value(); |
| 2484 } | 2508 } |
| 2485 | 2509 |
| 2486 bool GDataFileSystem::GetFileInfoByPath( | |
| 2487 const FilePath& file_path, GDataFileProperties* properties) { | |
| 2488 DCHECK(properties); | |
| 2489 base::AutoLock lock(lock_); | |
| 2490 GDataEntry* entry = GetGDataEntryByPath(file_path); | |
| 2491 if (!entry) | |
| 2492 return false; | |
| 2493 | |
| 2494 properties->file_info = entry->file_info(); | |
| 2495 properties->resource_id = entry->resource_id(); | |
| 2496 | |
| 2497 GDataFile* regular_file = entry->AsGDataFile(); | |
| 2498 if (regular_file) { | |
| 2499 properties->file_md5 = regular_file->file_md5(); | |
| 2500 properties->mime_type = regular_file->content_mime_type(); | |
| 2501 properties->content_url = regular_file->content_url(); | |
| 2502 properties->alternate_url = regular_file->alternate_url(); | |
| 2503 properties->is_hosted_document = regular_file->is_hosted_document(); | |
| 2504 } | |
| 2505 return true; | |
| 2506 } | |
| 2507 | |
| 2508 GDataEntry* GDataFileSystem::GetGDataEntryByPath( | 2510 GDataEntry* GDataFileSystem::GetGDataEntryByPath( |
| 2509 const FilePath& file_path) { | 2511 const FilePath& file_path) { |
| 2510 lock_.AssertAcquired(); | 2512 lock_.AssertAcquired(); |
| 2511 // Find directory element within the cached file system snapshot. | 2513 // Find directory element within the cached file system snapshot. |
| 2512 GDataEntry* entry = NULL; | 2514 GDataEntry* entry = NULL; |
| 2513 root_->FindEntryByPath(file_path, base::Bind(&ReadOnlyFindEntryCallback, | 2515 root_->FindEntryByPath(file_path, base::Bind(&ReadOnlyFindEntryCallback, |
| 2514 &entry)); | 2516 &entry)); |
| 2515 return entry; | 2517 return entry; |
| 2516 } | 2518 } |
| 2517 | 2519 |
| (...skipping 2553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5071 } | 5073 } |
| 5072 } | 5074 } |
| 5073 | 5075 |
| 5074 if (error != base::PLATFORM_FILE_OK) { | 5076 if (error != base::PLATFORM_FILE_OK) { |
| 5075 if (!callback.is_null()) | 5077 if (!callback.is_null()) |
| 5076 callback.Run(error, FilePath()); | 5078 callback.Run(error, FilePath()); |
| 5077 return; | 5079 return; |
| 5078 } | 5080 } |
| 5079 | 5081 |
| 5080 DCHECK(!file_info->gdata_entry().resource_id().empty()); | 5082 DCHECK(!file_info->gdata_entry().resource_id().empty()); |
| 5081 | 5083 GetResolvedFileByPath( |
| 5082 // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection. | 5084 file_path, |
| 5083 // Do not call GetFileByPathOnUIThread() directly for avoiding deadlock. | 5085 base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile, |
| 5084 // The current method is called as a callback from GetFileInfoByPathAsync(), | |
| 5085 // which is under the lock taken. | |
| 5086 base::MessageLoopProxy::current()->PostTask( | |
| 5087 FROM_HERE, | |
| 5088 base::Bind(&GDataFileSystem::GetFileByPathOnUIThread, | |
| 5089 ui_weak_ptr_, | 5086 ui_weak_ptr_, |
| 5090 file_path, | 5087 callback, |
| 5091 base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile, | 5088 base::Passed(&file_info)), |
| 5092 ui_weak_ptr_, | 5089 GetDownloadDataCallback(), |
| 5093 callback, | 5090 error, |
| 5094 base::Passed(&file_info)), | 5091 file_info.get()); |
| 5095 GetDownloadDataCallback())); | |
| 5096 } | 5092 } |
| 5097 | 5093 |
| 5098 void GDataFileSystem::OnGetFileCompleteForOpenFile( | 5094 void GDataFileSystem::OnGetFileCompleteForOpenFile( |
| 5099 const OpenFileCallback& callback, | 5095 const OpenFileCallback& callback, |
| 5100 scoped_ptr<GDataFileProto> file_info, | 5096 scoped_ptr<GDataFileProto> file_info, |
| 5101 base::PlatformFileError error, | 5097 base::PlatformFileError error, |
| 5102 const FilePath& file_path, | 5098 const FilePath& file_path, |
| 5103 const std::string& mime_type, | 5099 const std::string& mime_type, |
| 5104 GDataFileType file_type) { | 5100 GDataFileType file_type) { |
| 5105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 5101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5174 callback.Run(error); | 5170 callback.Run(error); |
| 5175 return; | 5171 return; |
| 5176 } | 5172 } |
| 5177 | 5173 |
| 5178 DCHECK(!file_info->gdata_entry().resource_id().empty()); | 5174 DCHECK(!file_info->gdata_entry().resource_id().empty()); |
| 5179 | 5175 |
| 5180 // TODO(benchan,kinaba): Call ClearDirtyInCache instead of CommitDirtyInCache | 5176 // TODO(benchan,kinaba): Call ClearDirtyInCache instead of CommitDirtyInCache |
| 5181 // if the file has not been modified. Come up with a way to detect the | 5177 // if the file has not been modified. Come up with a way to detect the |
| 5182 // intactness effectively, or provide a method for user to declare it when | 5178 // intactness effectively, or provide a method for user to declare it when |
| 5183 // calling CloseFile(). | 5179 // calling CloseFile(). |
| 5184 | 5180 CommitDirtyInCache( |
| 5185 // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection. | 5181 file_info->gdata_entry().resource_id(), |
| 5186 // Do not call CommitDirtyInCache() directly for avoiding deadlock. | 5182 file_info->file_md5(), |
| 5187 // The current method is called as a callback from GetFileInfoByPathAsync(), | |
| 5188 // which is under the lock taken. | |
| 5189 base::MessageLoopProxy::current()->PostTask( | |
| 5190 FROM_HERE, | |
| 5191 base::Bind( | 5183 base::Bind( |
| 5192 &GDataFileSystem::CommitDirtyInCache, | 5184 &GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile, |
| 5193 ui_weak_ptr_, | 5185 ui_weak_ptr_, |
| 5194 file_info->gdata_entry().resource_id(), | 5186 callback)); |
| 5195 file_info->file_md5(), | |
| 5196 base::Bind(&GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile, | |
| 5197 ui_weak_ptr_, | |
| 5198 callback))); | |
| 5199 } | 5187 } |
| 5200 | 5188 |
| 5201 void GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile( | 5189 void GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile( |
| 5202 const CloseFileCallback& callback, | 5190 const CloseFileCallback& callback, |
| 5203 base::PlatformFileError error, | 5191 base::PlatformFileError error, |
| 5204 const std::string& resource_id, | 5192 const std::string& resource_id, |
| 5205 const std::string& md5) { | 5193 const std::string& md5) { |
| 5206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 5194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 5207 | 5195 |
| 5208 if (!callback.is_null()) | 5196 if (!callback.is_null()) |
| 5209 callback.Run(error); | 5197 callback.Run(error); |
| 5210 } | 5198 } |
| 5211 | 5199 |
| 5212 } // namespace gdata | 5200 } // namespace gdata |
| OLD | NEW |