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 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 mime_type(mime_type), | 910 mime_type(mime_type), |
911 get_file_callback(get_file_callback), | 911 get_file_callback(get_file_callback), |
912 get_download_data_callback(get_download_data_callback) { | 912 get_download_data_callback(get_download_data_callback) { |
913 } | 913 } |
914 | 914 |
915 GDataFileSystem::GetFileFromCacheParams::~GetFileFromCacheParams() { | 915 GDataFileSystem::GetFileFromCacheParams::~GetFileFromCacheParams() { |
916 } | 916 } |
917 | 917 |
918 // GDataFileSystem class implementation. | 918 // GDataFileSystem class implementation. |
919 | 919 |
920 GDataFileSystem::GDataFileSystem(Profile* profile, | 920 GDataFileSystem::GDataFileSystem( |
921 DocumentsServiceInterface* documents_service) | 921 Profile* profile, |
| 922 GDataCache* cache, |
| 923 DocumentsServiceInterface* documents_service, |
| 924 const base::SequencedWorkerPool::SequenceToken& sequence_token) |
922 : profile_(profile), | 925 : profile_(profile), |
| 926 cache_(cache), |
923 documents_service_(documents_service), | 927 documents_service_(documents_service), |
924 on_io_completed_(new base::WaitableEvent( | 928 on_io_completed_(new base::WaitableEvent( |
925 true /* manual reset */, true /* initially signaled */)), | 929 true /* manual reset */, true /* initially signaled */)), |
926 num_pending_tasks_(0), | 930 num_pending_tasks_(0), |
927 update_timer_(true /* retain_user_task */, true /* is_repeating */), | 931 update_timer_(true /* retain_user_task */, true /* is_repeating */), |
928 hide_hosted_docs_(false), | 932 hide_hosted_docs_(false), |
929 ui_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST( | 933 ui_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST( |
930 new base::WeakPtrFactory<GDataFileSystem>(this))), | 934 new base::WeakPtrFactory<GDataFileSystem>(this))), |
931 ui_weak_ptr_(ui_weak_ptr_factory_->GetWeakPtr()), | 935 ui_weak_ptr_(ui_weak_ptr_factory_->GetWeakPtr()), |
932 sequence_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()) { | 936 sequence_token_(sequence_token) { |
933 // Should be created from the file browser extension API on UI thread. | 937 // Should be created from the file browser extension API on UI thread. |
934 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
935 } | 939 } |
936 | 940 |
937 void GDataFileSystem::Initialize() { | 941 void GDataFileSystem::Initialize() { |
938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 942 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
939 | 943 |
940 documents_service_->Initialize(profile_); | 944 documents_service_->Initialize(profile_); |
941 | 945 |
942 root_.reset(new GDataRootDirectory); | 946 root_.reset(new GDataRootDirectory); |
943 const FilePath cache_root_path = GDataCache::GetCacheRootPath(profile_); | |
944 cache_ = GDataCache::CreateGDataCache(cache_root_path, | |
945 BrowserThread::GetBlockingPool(), | |
946 sequence_token_).Pass(); | |
947 | 947 |
948 PrefService* pref_service = profile_->GetPrefs(); | 948 PrefService* pref_service = profile_->GetPrefs(); |
949 hide_hosted_docs_ = pref_service->GetBoolean(prefs::kDisableGDataHostedFiles); | 949 hide_hosted_docs_ = pref_service->GetBoolean(prefs::kDisableGDataHostedFiles); |
950 | 950 |
951 InitializePreferenceObserver(); | 951 InitializePreferenceObserver(); |
952 | 952 |
953 PostBlockingPoolSequencedTask( | 953 PostBlockingPoolSequencedTask( |
954 FROM_HERE, | 954 FROM_HERE, |
955 base::Bind(&GDataFileSystem::InitializeCacheOnBlockingPool, | 955 base::Bind(&GDataFileSystem::InitializeCacheOnBlockingPool, |
956 base::Unretained(this))); | 956 base::Unretained(this))); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 // other threads, we are safe to destroy the data members. | 1006 // other threads, we are safe to destroy the data members. |
1007 | 1007 |
1008 // Cancel all the in-flight operations. | 1008 // Cancel all the in-flight operations. |
1009 // This asynchronously cancels the URL fetch operations. | 1009 // This asynchronously cancels the URL fetch operations. |
1010 documents_service_->CancelAll(); | 1010 documents_service_->CancelAll(); |
1011 documents_service_ = NULL; | 1011 documents_service_ = NULL; |
1012 | 1012 |
1013 // Lock to let root destroy cache map and resource map. | 1013 // Lock to let root destroy cache map and resource map. |
1014 base::AutoLock lock(lock_); | 1014 base::AutoLock lock(lock_); |
1015 root_.reset(); | 1015 root_.reset(); |
1016 // TODO(satorux): Should not delete this on UI thread. crbug.com/131826. | |
1017 cache_.reset(); | |
1018 | 1016 |
1019 // Let's make sure that num_pending_tasks_lock_ has been released on all | 1017 // Let's make sure that num_pending_tasks_lock_ has been released on all |
1020 // other threads. | 1018 // other threads. |
1021 base::AutoLock tasks_lock(num_pending_tasks_lock_); | 1019 base::AutoLock tasks_lock(num_pending_tasks_lock_); |
1022 } | 1020 } |
1023 | 1021 |
1024 void GDataFileSystem::AddObserver(Observer* observer) { | 1022 void GDataFileSystem::AddObserver(Observer* observer) { |
1025 observers_.AddObserver(observer); | 1023 observers_.AddObserver(observer); |
1026 } | 1024 } |
1027 | 1025 |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2029 // document. | 2027 // document. |
2030 if (file_proto->is_hosted_document()) { | 2028 if (file_proto->is_hosted_document()) { |
2031 base::PlatformFileError* error = | 2029 base::PlatformFileError* error = |
2032 new base::PlatformFileError(base::PLATFORM_FILE_OK); | 2030 new base::PlatformFileError(base::PLATFORM_FILE_OK); |
2033 FilePath* temp_file_path = new FilePath; | 2031 FilePath* temp_file_path = new FilePath; |
2034 std::string* mime_type = new std::string; | 2032 std::string* mime_type = new std::string; |
2035 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); | 2033 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); |
2036 PostBlockingPoolSequencedTaskAndReply( | 2034 PostBlockingPoolSequencedTaskAndReply( |
2037 FROM_HERE, | 2035 FROM_HERE, |
2038 base::Bind(&CreateDocumentJsonFileOnBlockingPool, | 2036 base::Bind(&CreateDocumentJsonFileOnBlockingPool, |
2039 GetCacheDirectoryPath( | 2037 cache_->GetCacheDirectoryPath( |
2040 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), | 2038 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), |
2041 GURL(file_proto->alternate_url()), | 2039 GURL(file_proto->alternate_url()), |
2042 file_proto->gdata_entry().resource_id(), | 2040 file_proto->gdata_entry().resource_id(), |
2043 error, | 2041 error, |
2044 temp_file_path, | 2042 temp_file_path, |
2045 mime_type, | 2043 mime_type, |
2046 file_type), | 2044 file_type), |
2047 base::Bind(&RunGetFileCallbackHelper, | 2045 base::Bind(&RunGetFileCallbackHelper, |
2048 get_file_callback, | 2046 get_file_callback, |
2049 base::Owned(error), | 2047 base::Owned(error), |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 *has_enough_space = HasEnoughSpaceFor(num_bytes); | 2227 *has_enough_space = HasEnoughSpaceFor(num_bytes); |
2230 if (*has_enough_space) | 2228 if (*has_enough_space) |
2231 return; | 2229 return; |
2232 | 2230 |
2233 // Otherwise, try to free up the disk space. | 2231 // Otherwise, try to free up the disk space. |
2234 DVLOG(1) << "Freeing up disk space for " << num_bytes; | 2232 DVLOG(1) << "Freeing up disk space for " << num_bytes; |
2235 base::AutoLock lock(lock_); // For cache access. | 2233 base::AutoLock lock(lock_); // For cache access. |
2236 // First remove temporary files from the cache map. | 2234 // First remove temporary files from the cache map. |
2237 cache_->RemoveTemporaryFiles(); | 2235 cache_->RemoveTemporaryFiles(); |
2238 // Then remove all files under "tmp" directory. | 2236 // Then remove all files under "tmp" directory. |
2239 RemoveAllFiles(GetCacheDirectoryPath(GDataCache::CACHE_TYPE_TMP)); | 2237 RemoveAllFiles(cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_TMP)); |
2240 | 2238 |
2241 // Check the disk space again. | 2239 // Check the disk space again. |
2242 *has_enough_space = HasEnoughSpaceFor(num_bytes); | 2240 *has_enough_space = HasEnoughSpaceFor(num_bytes); |
2243 } | 2241 } |
2244 | 2242 |
2245 void GDataFileSystem::FreeDiskSpaceIfNeeded(bool* has_enough_space) { | 2243 void GDataFileSystem::FreeDiskSpaceIfNeeded(bool* has_enough_space) { |
2246 FreeDiskSpaceIfNeededFor(0, has_enough_space); | 2244 FreeDiskSpaceIfNeededFor(0, has_enough_space); |
2247 } | 2245 } |
2248 | 2246 |
2249 void GDataFileSystem::StartDownloadFileIfEnoughSpace( | 2247 void GDataFileSystem::StartDownloadFileIfEnoughSpace( |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2950 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); | 2948 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); |
2951 | 2949 |
2952 #ifndef NDEBUG | 2950 #ifndef NDEBUG |
2953 // Save initial root feed for analysis. | 2951 // Save initial root feed for analysis. |
2954 std::string file_name = | 2952 std::string file_name = |
2955 base::StringPrintf("DEBUG_feed_%d.json", | 2953 base::StringPrintf("DEBUG_feed_%d.json", |
2956 params->start_changestamp); | 2954 params->start_changestamp); |
2957 PostBlockingPoolSequencedTask( | 2955 PostBlockingPoolSequencedTask( |
2958 FROM_HERE, | 2956 FROM_HERE, |
2959 base::Bind(&SaveFeedOnBlockingPoolForDebugging, | 2957 base::Bind(&SaveFeedOnBlockingPoolForDebugging, |
2960 GetCacheDirectoryPath( | 2958 cache_->GetCacheDirectoryPath( |
2961 GDataCache::CACHE_TYPE_META).Append(file_name), | 2959 GDataCache::CACHE_TYPE_META).Append(file_name), |
2962 base::Passed(&data))); | 2960 base::Passed(&data))); |
2963 #endif | 2961 #endif |
2964 | 2962 |
2965 // Add the current feed to the list of collected feeds for this directory. | 2963 // Add the current feed to the list of collected feeds for this directory. |
2966 params->feed_list->push_back(current_feed.release()); | 2964 params->feed_list->push_back(current_feed.release()); |
2967 | 2965 |
2968 // Compute and notify the number of entries fetched so far. | 2966 // Compute and notify the number of entries fetched so far. |
2969 int num_accumulated_entries = 0; | 2967 int num_accumulated_entries = 0; |
2970 for (size_t i = 0; i < params->feed_list->size(); ++i) | 2968 for (size_t i = 0; i < params->feed_list->size(); ++i) |
(...skipping 30 matching lines...) Expand all Loading... |
3001 callback.Run(params, error); | 2999 callback.Run(params, error); |
3002 } | 3000 } |
3003 | 3001 |
3004 void GDataFileSystem::LoadRootFeedFromCache( | 3002 void GDataFileSystem::LoadRootFeedFromCache( |
3005 bool should_load_from_server, | 3003 bool should_load_from_server, |
3006 const FilePath& search_file_path, | 3004 const FilePath& search_file_path, |
3007 const FindEntryCallback& callback) { | 3005 const FindEntryCallback& callback) { |
3008 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 3006 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
3009 | 3007 |
3010 const FilePath path = | 3008 const FilePath path = |
3011 GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( | 3009 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( |
3012 kFilesystemProtoFile); | 3010 kFilesystemProtoFile); |
3013 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path, | 3011 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path, |
3014 should_load_from_server, | 3012 should_load_from_server, |
3015 callback); | 3013 callback); |
3016 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, | 3014 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, |
3017 base::Bind(&LoadProtoOnBlockingPool, path, params), | 3015 base::Bind(&LoadProtoOnBlockingPool, path, params), |
3018 base::Bind(&GDataFileSystem::OnProtoLoaded, | 3016 base::Bind(&GDataFileSystem::OnProtoLoaded, |
3019 ui_weak_ptr_, | 3017 ui_weak_ptr_, |
3020 base::Owned(params))); | 3018 base::Owned(params))); |
3021 } | 3019 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 void GDataFileSystem::SaveFileSystemAsProto() { | 3085 void GDataFileSystem::SaveFileSystemAsProto() { |
3088 DVLOG(1) << "SaveFileSystemAsProto"; | 3086 DVLOG(1) << "SaveFileSystemAsProto"; |
3089 base::AutoLock lock(lock_); // To access root_. | 3087 base::AutoLock lock(lock_); // To access root_. |
3090 | 3088 |
3091 if (!ShouldSerializeFileSystemNow(root_->serialized_size(), | 3089 if (!ShouldSerializeFileSystemNow(root_->serialized_size(), |
3092 root_->last_serialized())) { | 3090 root_->last_serialized())) { |
3093 return; | 3091 return; |
3094 } | 3092 } |
3095 | 3093 |
3096 const FilePath path = | 3094 const FilePath path = |
3097 GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( | 3095 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( |
3098 kFilesystemProtoFile); | 3096 kFilesystemProtoFile); |
3099 scoped_ptr<std::string> serialized_proto(new std::string()); | 3097 scoped_ptr<std::string> serialized_proto(new std::string()); |
3100 root_->SerializeToString(serialized_proto.get()); | 3098 root_->SerializeToString(serialized_proto.get()); |
3101 root_->set_last_serialized(base::Time::Now()); | 3099 root_->set_last_serialized(base::Time::Now()); |
3102 root_->set_serialized_size(serialized_proto->size()); | 3100 root_->set_serialized_size(serialized_proto->size()); |
3103 PostBlockingPoolSequencedTask( | 3101 PostBlockingPoolSequencedTask( |
3104 FROM_HERE, | 3102 FROM_HERE, |
3105 base::Bind(&SaveProtoOnBlockingPool, path, | 3103 base::Bind(&SaveProtoOnBlockingPool, path, |
3106 base::Passed(serialized_proto.Pass()))); | 3104 base::Passed(serialized_proto.Pass()))); |
3107 } | 3105 } |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3948 hide_hosted_docs_ = hide; | 3946 hide_hosted_docs_ = hide; |
3949 root_path = root_->GetFilePath(); | 3947 root_path = root_->GetFilePath(); |
3950 } | 3948 } |
3951 | 3949 |
3952 // Kick of directory refresh when this setting changes. | 3950 // Kick of directory refresh when this setting changes. |
3953 NotifyDirectoryChanged(root_path); | 3951 NotifyDirectoryChanged(root_path); |
3954 } | 3952 } |
3955 | 3953 |
3956 //===================== GDataFileSystem: Cache entry points ==================== | 3954 //===================== GDataFileSystem: Cache entry points ==================== |
3957 | 3955 |
3958 bool GDataFileSystem::IsUnderGDataCacheDirectory(const FilePath& path) const { | |
3959 return cache_->IsUnderGDataCacheDirectory(path); | |
3960 } | |
3961 | |
3962 FilePath GDataFileSystem::GetCacheDirectoryPath( | |
3963 GDataCache::CacheSubDirectoryType sub_dir_type) const { | |
3964 return cache_->GetCacheDirectoryPath(sub_dir_type); | |
3965 } | |
3966 | |
3967 FilePath GDataFileSystem::GetCacheFilePath( | |
3968 const std::string& resource_id, | |
3969 const std::string& md5, | |
3970 GDataCache::CacheSubDirectoryType sub_dir_type, | |
3971 GDataCache::CachedFileOrigin file_origin) const { | |
3972 return cache_->GetCacheFilePath(resource_id, md5, sub_dir_type, file_origin); | |
3973 } | |
3974 | |
3975 void GDataFileSystem::StoreToCache(const std::string& resource_id, | 3956 void GDataFileSystem::StoreToCache(const std::string& resource_id, |
3976 const std::string& md5, | 3957 const std::string& md5, |
3977 const FilePath& source_path, | 3958 const FilePath& source_path, |
3978 FileOperationType file_operation_type, | 3959 FileOperationType file_operation_type, |
3979 const CacheOperationCallback& callback) { | 3960 const CacheOperationCallback& callback) { |
3980 base::PlatformFileError* error = | 3961 base::PlatformFileError* error = |
3981 new base::PlatformFileError(base::PLATFORM_FILE_OK); | 3962 new base::PlatformFileError(base::PLATFORM_FILE_OK); |
3982 PostBlockingPoolSequencedTaskAndReply( | 3963 PostBlockingPoolSequencedTaskAndReply( |
3983 FROM_HERE, | 3964 FROM_HERE, |
3984 base::Bind(&GDataFileSystem::StoreToCacheOnBlockingPool, | 3965 base::Bind(&GDataFileSystem::StoreToCacheOnBlockingPool, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4145 void GDataFileSystem::InitializeCacheOnBlockingPool() { | 4126 void GDataFileSystem::InitializeCacheOnBlockingPool() { |
4146 DCHECK(IsRunningSequenceOnCurrentThread(sequence_token_)); | 4127 DCHECK(IsRunningSequenceOnCurrentThread(sequence_token_)); |
4147 | 4128 |
4148 base::PlatformFileError error = CreateCacheDirectories(cache_->cache_paths()); | 4129 base::PlatformFileError error = CreateCacheDirectories(cache_->cache_paths()); |
4149 if (error != base::PLATFORM_FILE_OK) | 4130 if (error != base::PLATFORM_FILE_OK) |
4150 return; | 4131 return; |
4151 | 4132 |
4152 // Change permissions of cache persistent directory to u+rwx,og+x in order to | 4133 // Change permissions of cache persistent directory to u+rwx,og+x in order to |
4153 // allow archive files in that directory to be mounted by cros-disks. | 4134 // allow archive files in that directory to be mounted by cros-disks. |
4154 error = ChangeFilePermissions( | 4135 error = ChangeFilePermissions( |
4155 GetCacheDirectoryPath(GDataCache::CACHE_TYPE_PERSISTENT), | 4136 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_PERSISTENT), |
4156 S_IRWXU | S_IXGRP | S_IXOTH); | 4137 S_IRWXU | S_IXGRP | S_IXOTH); |
4157 if (error != base::PLATFORM_FILE_OK) | 4138 if (error != base::PLATFORM_FILE_OK) |
4158 return; | 4139 return; |
4159 | 4140 |
4160 DVLOG(1) << "Scanning directories"; | 4141 DVLOG(1) << "Scanning directories"; |
4161 | 4142 |
4162 // Scan cache persistent and tmp directories to enumerate all files and create | 4143 // Scan cache persistent and tmp directories to enumerate all files and create |
4163 // corresponding entries for cache map. | 4144 // corresponding entries for cache map. |
4164 GDataCache::CacheMap cache_map; | 4145 GDataCache::CacheMap cache_map; |
4165 ScanCacheDirectory(GDataCache::CACHE_TYPE_PERSISTENT, &cache_map); | 4146 ScanCacheDirectory(GDataCache::CACHE_TYPE_PERSISTENT, &cache_map); |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4889 base::Unretained(this), | 4870 base::Unretained(this), |
4890 base::Owned(has_enough_space))); | 4871 base::Owned(has_enough_space))); |
4891 } | 4872 } |
4892 | 4873 |
4893 //============= GDataFileSystem: internal helper functions ===================== | 4874 //============= GDataFileSystem: internal helper functions ===================== |
4894 | 4875 |
4895 void GDataFileSystem::ScanCacheDirectory( | 4876 void GDataFileSystem::ScanCacheDirectory( |
4896 GDataCache::CacheSubDirectoryType sub_dir_type, | 4877 GDataCache::CacheSubDirectoryType sub_dir_type, |
4897 GDataCache::CacheMap* cache_map) { | 4878 GDataCache::CacheMap* cache_map) { |
4898 file_util::FileEnumerator enumerator( | 4879 file_util::FileEnumerator enumerator( |
4899 GetCacheDirectoryPath(sub_dir_type), | 4880 cache_->GetCacheDirectoryPath(sub_dir_type), |
4900 false, // not recursive | 4881 false, // not recursive |
4901 static_cast<file_util::FileEnumerator::FileType>( | 4882 static_cast<file_util::FileEnumerator::FileType>( |
4902 file_util::FileEnumerator::FILES | | 4883 file_util::FileEnumerator::FILES | |
4903 file_util::FileEnumerator::SHOW_SYM_LINKS), | 4884 file_util::FileEnumerator::SHOW_SYM_LINKS), |
4904 kWildCard); | 4885 kWildCard); |
4905 for (FilePath current = enumerator.Next(); !current.empty(); | 4886 for (FilePath current = enumerator.Next(); !current.empty(); |
4906 current = enumerator.Next()) { | 4887 current = enumerator.Next()) { |
4907 // Extract resource_id and md5 from filename. | 4888 // Extract resource_id and md5 from filename. |
4908 std::string resource_id; | 4889 std::string resource_id; |
4909 std::string md5; | 4890 std::string md5; |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5203 base::PlatformFileError error, | 5184 base::PlatformFileError error, |
5204 const std::string& resource_id, | 5185 const std::string& resource_id, |
5205 const std::string& md5) { | 5186 const std::string& md5) { |
5206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 5187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
5207 | 5188 |
5208 if (!callback.is_null()) | 5189 if (!callback.is_null()) |
5209 callback.Run(error); | 5190 callback.Run(error); |
5210 } | 5191 } |
5211 | 5192 |
5212 } // namespace gdata | 5193 } // namespace gdata |
OLD | NEW |