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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
886 // Returns callback which runs the given |callback| on the current thread. | 886 // Returns callback which runs the given |callback| on the current thread. |
887 template<typename CallbackType> | 887 template<typename CallbackType> |
888 CallbackType CreateRelayCallback(const CallbackType& callback) { | 888 CallbackType CreateRelayCallback(const CallbackType& callback) { |
889 return base::Bind(&RelayCallback<CallbackType>::Run, | 889 return base::Bind(&RelayCallback<CallbackType>::Run, |
890 base::MessageLoopProxy::current(), | 890 base::MessageLoopProxy::current(), |
891 callback); | 891 callback); |
892 } | 892 } |
893 | 893 |
894 } // namespace | 894 } // namespace |
895 | 895 |
896 // GDataFileProperties struct implementation. | |
897 | |
898 GDataFileProperties::GDataFileProperties() : is_hosted_document(false) { | |
899 } | |
900 | |
901 GDataFileProperties::~GDataFileProperties() { | |
902 } | |
903 | |
904 // GDataFileSystem::GetDocumentsParams struct implementation. | 896 // GDataFileSystem::GetDocumentsParams struct implementation. |
905 | 897 |
906 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( | 898 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
907 int start_changestamp, | 899 int start_changestamp, |
908 int root_feed_changestamp, | 900 int root_feed_changestamp, |
909 std::vector<DocumentFeed*>* feed_list, | 901 std::vector<DocumentFeed*>* feed_list, |
910 bool should_fetch_multiple_feeds, | 902 bool should_fetch_multiple_feeds, |
911 const FilePath& search_file_path, | 903 const FilePath& search_file_path, |
912 const std::string& search_query, | 904 const std::string& search_query, |
913 const std::string& directory_resource_id, | 905 const std::string& directory_resource_id, |
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2015 callback))); | 2007 callback))); |
2016 } | 2008 } |
2017 | 2009 |
2018 void GDataFileSystem::GetFileByPath( | 2010 void GDataFileSystem::GetFileByPath( |
2019 const FilePath& file_path, | 2011 const FilePath& file_path, |
2020 const GetFileCallback& get_file_callback, | 2012 const GetFileCallback& get_file_callback, |
2021 const GetDownloadDataCallback& get_download_data_callback) { | 2013 const GetDownloadDataCallback& get_download_data_callback) { |
2022 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2014 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
2023 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2015 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
2024 RunTaskOnUIThread( | 2016 RunTaskOnUIThread( |
2025 base::Bind(&GDataFileSystem::GetFileByPathOnUIThread, | 2017 base::Bind(&GDataFileSystem::GetFileInfoByPathAsync, |
satorux1
2012/06/07 22:47:17
Can you keep the function as before? We use this p
hshi1
2012/06/08 00:22:05
Done.
Note that I have to create a common shared
| |
2026 ui_weak_ptr_, | 2018 ui_weak_ptr_, |
2027 file_path, | 2019 file_path, |
2028 CreateRelayCallback(get_file_callback), | 2020 base::Bind( |
2029 CreateRelayCallback(get_download_data_callback))); | 2021 &GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath, |
2022 ui_weak_ptr_, | |
2023 file_path, | |
2024 CreateRelayCallback(get_file_callback), | |
2025 CreateRelayCallback(get_download_data_callback)))); | |
2026 } | |
2027 | |
2028 void GDataFileSystem::OnGetFileInfoCompleteForGetFileByPath( | |
2029 const FilePath& file_path, | |
2030 const GetFileCallback& get_file_callback, | |
2031 const GetDownloadDataCallback& get_download_data_callback, | |
2032 base::PlatformFileError error, | |
2033 scoped_ptr<GDataFileProto> file_info) { | |
2034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
2035 | |
2036 DCHECK(!file_info->gdata_entry().resource_id().empty()); | |
2037 GetFileByPathOnUIThread(file_path, | |
2038 get_file_callback, | |
2039 get_download_data_callback, | |
2040 error, | |
2041 file_info.get()); | |
2030 } | 2042 } |
2031 | 2043 |
2032 void GDataFileSystem::GetFileByPathOnUIThread( | 2044 void GDataFileSystem::GetFileByPathOnUIThread( |
2033 const FilePath& file_path, | 2045 const FilePath& file_path, |
2034 const GetFileCallback& get_file_callback, | 2046 const GetFileCallback& get_file_callback, |
2035 const GetDownloadDataCallback& get_download_data_callback) { | 2047 const GetDownloadDataCallback& get_download_data_callback, |
2048 base::PlatformFileError error, | |
2049 const GDataFileProto* file_proto) { | |
2036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2050 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
satorux1
2012/06/07 22:47:17
DCHECK(file_proto);
hshi1
2012/06/08 00:22:05
Actually file_proto can be NULL. It is checked in
| |
2037 | 2051 |
2038 GDataFileProperties file_properties; | 2052 if (error != base::PLATFORM_FILE_OK || !file_proto) { |
2039 if (!GetFileInfoByPath(file_path, &file_properties)) { | |
2040 if (!get_file_callback.is_null()) { | 2053 if (!get_file_callback.is_null()) { |
2041 MessageLoop::current()->PostTask( | 2054 MessageLoop::current()->PostTask( |
2042 FROM_HERE, | 2055 FROM_HERE, |
2043 base::Bind(get_file_callback, | 2056 base::Bind(get_file_callback, |
2044 base::PLATFORM_FILE_ERROR_NOT_FOUND, | 2057 base::PLATFORM_FILE_ERROR_NOT_FOUND, |
2045 FilePath(), | 2058 FilePath(), |
2046 std::string(), | 2059 std::string(), |
2047 REGULAR_FILE)); | 2060 REGULAR_FILE)); |
2048 } | 2061 } |
2049 return; | 2062 return; |
2050 } | 2063 } |
2051 | 2064 |
2052 // For a hosted document, we create a special JSON file to represent the | 2065 // For a hosted document, we create a special JSON file to represent the |
2053 // document instead of fetching the document content in one of the exported | 2066 // document instead of fetching the document content in one of the exported |
2054 // formats. The JSON file contains the edit URL and resource ID of the | 2067 // formats. The JSON file contains the edit URL and resource ID of the |
2055 // document. | 2068 // document. |
2056 if (file_properties.is_hosted_document) { | 2069 if (file_proto->is_hosted_document()) { |
2057 base::PlatformFileError* error = | 2070 base::PlatformFileError* error = |
2058 new base::PlatformFileError(base::PLATFORM_FILE_OK); | 2071 new base::PlatformFileError(base::PLATFORM_FILE_OK); |
2059 FilePath* temp_file_path = new FilePath; | 2072 FilePath* temp_file_path = new FilePath; |
2060 std::string* mime_type = new std::string; | 2073 std::string* mime_type = new std::string; |
2061 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); | 2074 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); |
2062 PostBlockingPoolSequencedTaskAndReply( | 2075 PostBlockingPoolSequencedTaskAndReply( |
2063 FROM_HERE, | 2076 FROM_HERE, |
2064 base::Bind(&CreateDocumentJsonFileOnIOThreadPool, | 2077 base::Bind(&CreateDocumentJsonFileOnIOThreadPool, |
2065 GetCacheDirectoryPath( | 2078 GetCacheDirectoryPath( |
2066 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), | 2079 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), |
2067 file_properties.alternate_url, | 2080 GURL(file_proto->alternate_url()), |
2068 file_properties.resource_id, | 2081 file_proto->gdata_entry().resource_id(), |
2069 error, | 2082 error, |
2070 temp_file_path, | 2083 temp_file_path, |
2071 mime_type, | 2084 mime_type, |
2072 file_type), | 2085 file_type), |
2073 base::Bind(&RunGetFileCallbackHelper, | 2086 base::Bind(&RunGetFileCallbackHelper, |
2074 get_file_callback, | 2087 get_file_callback, |
2075 base::Owned(error), | 2088 base::Owned(error), |
2076 base::Owned(temp_file_path), | 2089 base::Owned(temp_file_path), |
2077 base::Owned(mime_type), | 2090 base::Owned(mime_type), |
2078 base::Owned(file_type))); | 2091 base::Owned(file_type))); |
2079 return; | 2092 return; |
2080 } | 2093 } |
2081 | 2094 |
2082 // Returns absolute path of the file if it were cached or to be cached. | 2095 // Returns absolute path of the file if it were cached or to be cached. |
2083 FilePath local_tmp_path = GetCacheFilePath(file_properties.resource_id, | 2096 FilePath local_tmp_path = GetCacheFilePath( |
2084 file_properties.file_md5, | 2097 file_proto->gdata_entry().resource_id(), |
2085 GDataCache::CACHE_TYPE_TMP, | 2098 file_proto->file_md5(), |
2086 CACHED_FILE_FROM_SERVER); | 2099 GDataCache::CACHE_TYPE_TMP, |
2100 CACHED_FILE_FROM_SERVER); | |
2087 GetFileFromCacheByResourceIdAndMd5( | 2101 GetFileFromCacheByResourceIdAndMd5( |
2088 file_properties.resource_id, | 2102 file_proto->gdata_entry().resource_id(), |
2089 file_properties.file_md5, | 2103 file_proto->file_md5(), |
2090 base::Bind( | 2104 base::Bind( |
2091 &GDataFileSystem::OnGetFileFromCache, | 2105 &GDataFileSystem::OnGetFileFromCache, |
2092 ui_weak_ptr_, | 2106 ui_weak_ptr_, |
2093 GetFileFromCacheParams(file_path, | 2107 GetFileFromCacheParams(file_path, |
2094 local_tmp_path, | 2108 local_tmp_path, |
2095 file_properties.content_url, | 2109 GURL(file_proto->gdata_entry().content_url()), |
2096 file_properties.resource_id, | 2110 file_proto->gdata_entry().resource_id(), |
2097 file_properties.file_md5, | 2111 file_proto->file_md5(), |
2098 file_properties.mime_type, | 2112 file_proto->content_mime_type(), |
2099 get_file_callback, | 2113 get_file_callback, |
2100 get_download_data_callback))); | 2114 get_download_data_callback))); |
2101 } | 2115 } |
2102 | 2116 |
2103 void GDataFileSystem::GetFileByResourceId( | 2117 void GDataFileSystem::GetFileByResourceId( |
2104 const std::string& resource_id, | 2118 const std::string& resource_id, |
2105 const GetFileCallback& get_file_callback, | 2119 const GetFileCallback& get_file_callback, |
2106 const GetDownloadDataCallback& get_download_data_callback) { | 2120 const GetDownloadDataCallback& get_download_data_callback) { |
2107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
2108 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2122 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2547 directory->AddEntry(entry.release()); | 2561 directory->AddEntry(entry.release()); |
2548 } | 2562 } |
2549 | 2563 |
2550 // Note that there may be no change in the directory, but it's expensive to | 2564 // Note that there may be no change in the directory, but it's expensive to |
2551 // check if the new metadata matches the existing one, so we just always | 2565 // check if the new metadata matches the existing one, so we just always |
2552 // notify that the directory is changed. | 2566 // notify that the directory is changed. |
2553 NotifyDirectoryChanged(directory_path); | 2567 NotifyDirectoryChanged(directory_path); |
2554 DVLOG(1) << "Directory refreshed: " << directory_path.value(); | 2568 DVLOG(1) << "Directory refreshed: " << directory_path.value(); |
2555 } | 2569 } |
2556 | 2570 |
2557 bool GDataFileSystem::GetFileInfoByPath( | |
2558 const FilePath& file_path, GDataFileProperties* properties) { | |
2559 DCHECK(properties); | |
2560 base::AutoLock lock(lock_); | |
2561 GDataEntry* entry = GetGDataEntryByPath(file_path); | |
2562 if (!entry) | |
2563 return false; | |
2564 | |
2565 properties->file_info = entry->file_info(); | |
2566 properties->resource_id = entry->resource_id(); | |
2567 | |
2568 GDataFile* regular_file = entry->AsGDataFile(); | |
2569 if (regular_file) { | |
2570 properties->file_md5 = regular_file->file_md5(); | |
2571 properties->mime_type = regular_file->content_mime_type(); | |
2572 properties->content_url = regular_file->content_url(); | |
2573 properties->alternate_url = regular_file->alternate_url(); | |
2574 properties->is_hosted_document = regular_file->is_hosted_document(); | |
2575 } | |
2576 return true; | |
2577 } | |
2578 | |
2579 GDataEntry* GDataFileSystem::GetGDataEntryByPath( | 2571 GDataEntry* GDataFileSystem::GetGDataEntryByPath( |
2580 const FilePath& file_path) { | 2572 const FilePath& file_path) { |
2581 lock_.AssertAcquired(); | 2573 lock_.AssertAcquired(); |
2582 // Find directory element within the cached file system snapshot. | 2574 // Find directory element within the cached file system snapshot. |
2583 GDataEntry* entry = NULL; | 2575 GDataEntry* entry = NULL; |
2584 root_->FindEntryByPath(file_path, base::Bind(&ReadOnlyFindEntryCallback, | 2576 root_->FindEntryByPath(file_path, base::Bind(&ReadOnlyFindEntryCallback, |
2585 &entry)); | 2577 &entry)); |
2586 return entry; | 2578 return entry; |
2587 } | 2579 } |
2588 | 2580 |
(...skipping 2551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5140 } | 5132 } |
5141 } | 5133 } |
5142 | 5134 |
5143 if (error != base::PLATFORM_FILE_OK) { | 5135 if (error != base::PLATFORM_FILE_OK) { |
5144 if (!callback.is_null()) | 5136 if (!callback.is_null()) |
5145 callback.Run(error, FilePath()); | 5137 callback.Run(error, FilePath()); |
5146 return; | 5138 return; |
5147 } | 5139 } |
5148 | 5140 |
5149 DCHECK(!file_info->gdata_entry().resource_id().empty()); | 5141 DCHECK(!file_info->gdata_entry().resource_id().empty()); |
5150 | 5142 GetFileByPathOnUIThread( |
5151 // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection. | 5143 file_path, |
5152 // Do not call GetFileByPathOnUIThread() directly for avoiding deadlock. | 5144 base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile, |
5153 // The current method is called as a callback from GetFileInfoByPathAsync(), | |
5154 // which is under the lock taken. | |
5155 base::MessageLoopProxy::current()->PostTask( | |
5156 FROM_HERE, | |
5157 base::Bind(&GDataFileSystem::GetFileByPathOnUIThread, | |
5158 ui_weak_ptr_, | 5145 ui_weak_ptr_, |
5159 file_path, | 5146 callback, |
5160 base::Bind(&GDataFileSystem::OnGetFileCompleteForOpenFile, | 5147 base::Passed(&file_info)), |
5161 ui_weak_ptr_, | 5148 GetDownloadDataCallback(), |
5162 callback, | 5149 error, |
5163 base::Passed(&file_info)), | 5150 file_info.get()); |
5164 GetDownloadDataCallback())); | |
5165 } | 5151 } |
5166 | 5152 |
5167 void GDataFileSystem::OnGetFileCompleteForOpenFile( | 5153 void GDataFileSystem::OnGetFileCompleteForOpenFile( |
5168 const OpenFileCallback& callback, | 5154 const OpenFileCallback& callback, |
5169 scoped_ptr<GDataFileProto> file_info, | 5155 scoped_ptr<GDataFileProto> file_info, |
5170 base::PlatformFileError error, | 5156 base::PlatformFileError error, |
5171 const FilePath& file_path, | 5157 const FilePath& file_path, |
5172 const std::string& mime_type, | 5158 const std::string& mime_type, |
5173 GDataFileType file_type) { | 5159 GDataFileType file_type) { |
5174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 5160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5243 callback.Run(error); | 5229 callback.Run(error); |
5244 return; | 5230 return; |
5245 } | 5231 } |
5246 | 5232 |
5247 DCHECK(!file_info->gdata_entry().resource_id().empty()); | 5233 DCHECK(!file_info->gdata_entry().resource_id().empty()); |
5248 | 5234 |
5249 // TODO(benchan,kinaba): Call ClearDirtyInCache instead of CommitDirtyInCache | 5235 // TODO(benchan,kinaba): Call ClearDirtyInCache instead of CommitDirtyInCache |
5250 // if the file has not been modified. Come up with a way to detect the | 5236 // if the file has not been modified. Come up with a way to detect the |
5251 // intactness effectively, or provide a method for user to declare it when | 5237 // intactness effectively, or provide a method for user to declare it when |
5252 // calling CloseFile(). | 5238 // calling CloseFile(). |
5253 | 5239 CommitDirtyInCache( |
5254 // TODO(kinaba): once it is cleaned up (crbug/127048), remove the indirection. | 5240 file_info->gdata_entry().resource_id(), |
5255 // Do not call CommitDirtyInCache() directly for avoiding deadlock. | 5241 file_info->file_md5(), |
5256 // The current method is called as a callback from GetFileInfoByPathAsync(), | |
5257 // which is under the lock taken. | |
5258 base::MessageLoopProxy::current()->PostTask( | |
5259 FROM_HERE, | |
5260 base::Bind( | 5242 base::Bind( |
5261 &GDataFileSystem::CommitDirtyInCache, | 5243 &GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile, |
5262 ui_weak_ptr_, | 5244 ui_weak_ptr_, |
5263 file_info->gdata_entry().resource_id(), | 5245 callback)); |
5264 file_info->file_md5(), | |
5265 base::Bind(&GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile, | |
5266 ui_weak_ptr_, | |
5267 callback))); | |
5268 } | 5246 } |
5269 | 5247 |
5270 void GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile( | 5248 void GDataFileSystem::OnCommitDirtyInCacheCompleteForCloseFile( |
5271 const CloseFileCallback& callback, | 5249 const CloseFileCallback& callback, |
5272 base::PlatformFileError error, | 5250 base::PlatformFileError error, |
5273 const std::string& resource_id, | 5251 const std::string& resource_id, |
5274 const std::string& md5) { | 5252 const std::string& md5) { |
5275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 5253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
5276 | 5254 |
5277 if (!callback.is_null()) | 5255 if (!callback.is_null()) |
5278 callback.Run(error); | 5256 callback.Run(error); |
5279 } | 5257 } |
5280 | 5258 |
5281 } // namespace gdata | 5259 } // namespace gdata |
OLD | NEW |