Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_file_system.cc

Issue 10834170: gdata: Move GDataWapiFeedLoader to a set of new files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clang fix Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/file_util.h" 11 #include "base/file_util.h"
13 #include "base/json/json_file_value_serializer.h" 12 #include "base/json/json_file_value_serializer.h"
14 #include "base/json/json_reader.h"
15 #include "base/json/json_writer.h"
16 #include "base/message_loop.h" 13 #include "base/message_loop.h"
17 #include "base/message_loop_proxy.h" 14 #include "base/message_loop_proxy.h"
18 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
19 #include "base/platform_file.h" 16 #include "base/platform_file.h"
20 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/values.h" 18 #include "base/values.h"
22 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h" 19 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h"
23 #include "chrome/browser/chromeos/gdata/gdata.pb.h" 20 #include "chrome/browser/chromeos/gdata/gdata.pb.h"
24 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" 21 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h"
25 #include "chrome/browser/chromeos/gdata/gdata_download_observer.h" 22 #include "chrome/browser/chromeos/gdata/gdata_download_observer.h"
26 #include "chrome/browser/chromeos/gdata/gdata_protocol_handler.h" 23 #include "chrome/browser/chromeos/gdata/gdata_protocol_handler.h"
27 #include "chrome/browser/chromeos/gdata/gdata_system_service.h" 24 #include "chrome/browser/chromeos/gdata/gdata_system_service.h"
28 #include "chrome/browser/chromeos/gdata/gdata_util.h" 25 #include "chrome/browser/chromeos/gdata/gdata_util.h"
29 #include "chrome/browser/prefs/pref_service.h" 26 #include "chrome/browser/prefs/pref_service.h"
30 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/chrome_notification_types.h" 28 #include "chrome/common/chrome_notification_types.h"
33 #include "chrome/common/pref_names.h" 29 #include "chrome/common/pref_names.h"
34 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/notification_details.h" 31 #include "content/public/browser/notification_details.h"
36 #include "net/base/mime_util.h" 32 #include "net/base/mime_util.h"
37 33
38 using content::BrowserThread; 34 using content::BrowserThread;
39 35
40 namespace gdata { 36 namespace gdata {
41 namespace { 37 namespace {
42 38
43 const char kMimeTypeJson[] = "application/json"; 39 const char kMimeTypeJson[] = "application/json";
44 const char kMimeTypeOctetStream[] = "application/octet-stream"; 40 const char kMimeTypeOctetStream[] = "application/octet-stream";
45 41
46 const FilePath::CharType kAccountMetadataFile[] =
47 FILE_PATH_LITERAL("account_metadata.json");
48 const FilePath::CharType kFilesystemProtoFile[] =
49 FILE_PATH_LITERAL("file_system.pb");
50 const FilePath::CharType kResourceMetadataDBFile[] =
51 FILE_PATH_LITERAL("resource_metadata.db");
52
53 const char kEmptyFilePath[] = "/dev/null"; 42 const char kEmptyFilePath[] = "/dev/null";
54 43
55 // GData update check interval (in seconds). 44 // GData update check interval (in seconds).
56 #ifndef NDEBUG 45 #ifndef NDEBUG
57 const int kGDataUpdateCheckIntervalInSec = 5; 46 const int kGDataUpdateCheckIntervalInSec = 5;
58 #else 47 #else
59 const int kGDataUpdateCheckIntervalInSec = 60; 48 const int kGDataUpdateCheckIntervalInSec = 60;
60 #endif 49 #endif
61 50
62 // Update the fetch progress UI per every this number of feeds.
63 const int kFetchUiUpdateStep = 10;
64
65 // Schedule for dumping root file system proto buffers to disk depending its
66 // total protobuffer size in MB.
67 typedef struct {
68 double size;
69 int timeout;
70 } SerializationTimetable;
71
72 SerializationTimetable kSerializeTimetable[] = {
73 #ifndef NDEBUG
74 {0.5, 0}, // Less than 0.5MB, dump immediately.
75 {-1, 1}, // Any size, dump if older than 1 minute.
76 #else
77 {0.5, 0}, // Less than 0.5MB, dump immediately.
78 {1.0, 15}, // Less than 1.0MB, dump after 15 minutes.
79 {2.0, 30},
80 {4.0, 60},
81 {-1, 120}, // Any size, dump if older than 120 minutes.
82 #endif
83 };
84
85 // Returns true if file system is due to be serialized on disk based on it
86 // |serialized_size| and |last_serialized| timestamp.
87 bool ShouldSerializeFileSystemNow(size_t serialized_size,
88 const base::Time& last_serialized) {
89 const double size_in_mb = serialized_size / 1048576.0;
90 const int last_proto_dump_in_min =
91 (base::Time::Now() - last_serialized).InMinutes();
92 for (size_t i = 0; i < arraysize(kSerializeTimetable); i++) {
93 if ((size_in_mb < kSerializeTimetable[i].size ||
94 kSerializeTimetable[i].size == -1) &&
95 last_proto_dump_in_min >= kSerializeTimetable[i].timeout) {
96 return true;
97 }
98 }
99 return false;
100 }
101
102 // Converts gdata error code into file platform error code.
103 GDataFileError GDataToGDataFileError(GDataErrorCode status) {
104 switch (status) {
105 case HTTP_SUCCESS:
106 case HTTP_CREATED:
107 return GDATA_FILE_OK;
108 case HTTP_UNAUTHORIZED:
109 case HTTP_FORBIDDEN:
110 return GDATA_FILE_ERROR_ACCESS_DENIED;
111 case HTTP_NOT_FOUND:
112 return GDATA_FILE_ERROR_NOT_FOUND;
113 case GDATA_PARSE_ERROR:
114 case GDATA_FILE_ERROR:
115 return GDATA_FILE_ERROR_ABORT;
116 case GDATA_NO_CONNECTION:
117 return GDATA_FILE_ERROR_NO_CONNECTION;
118 default:
119 return GDATA_FILE_ERROR_FAILED;
120 }
121 }
122
123 //================================ Helper functions ============================ 51 //================================ Helper functions ============================
124 52
125 // Invoked upon completion of TransferRegularFile initiated by Copy. 53 // Invoked upon completion of TransferRegularFile initiated by Copy.
126 // 54 //
127 // |callback| is run on the thread represented by |relay_proxy|. 55 // |callback| is run on the thread represented by |relay_proxy|.
128 void OnTransferRegularFileCompleteForCopy( 56 void OnTransferRegularFileCompleteForCopy(
129 const FileOperationCallback& callback, 57 const FileOperationCallback& callback,
130 scoped_refptr<base::MessageLoopProxy> relay_proxy, 58 scoped_refptr<base::MessageLoopProxy> relay_proxy,
131 GDataFileError error) { 59 GDataFileError error) {
132 if (!callback.is_null()) 60 if (!callback.is_null())
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 base::MessageLoopProxy::current()->PostTask(FROM_HERE, callback_); 121 base::MessageLoopProxy::current()->PostTask(FROM_HERE, callback_);
194 file_system_->RemoveObserver(this); 122 file_system_->RemoveObserver(this);
195 base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this); 123 base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this);
196 } 124 }
197 125
198 private: 126 private:
199 GDataFileSystemInterface* file_system_; 127 GDataFileSystemInterface* file_system_;
200 base::Closure callback_; 128 base::Closure callback_;
201 }; 129 };
202 130
203 // Saves the string |serialized_proto| to a file at |path| on a blocking thread.
204 void SaveProtoOnBlockingPool(const FilePath& path,
205 scoped_ptr<std::string> serialized_proto) {
206 const int file_size = static_cast<int>(serialized_proto->length());
207 if (file_util::WriteFile(path, serialized_proto->data(), file_size) !=
208 file_size) {
209 LOG(WARNING) << "GData proto file can't be stored at "
210 << path.value();
211 if (!file_util::Delete(path, true)) {
212 LOG(WARNING) << "GData proto file can't be deleted at "
213 << path.value();
214 }
215 }
216 }
217
218 // Loads the file at |path| into the string |serialized_proto| on a blocking
219 // thread.
220 void LoadProtoOnBlockingPool(const FilePath& path,
221 LoadRootFeedParams* params) {
222 base::PlatformFileInfo info;
223 if (!file_util::GetFileInfo(path, &info)) {
224 params->load_error = GDATA_FILE_ERROR_NOT_FOUND;
225 return;
226 }
227 params->last_modified = info.last_modified;
228 if (!file_util::ReadFileToString(path, &params->proto)) {
229 LOG(WARNING) << "Proto file not found at " << path.value();
230 params->load_error = GDATA_FILE_ERROR_NOT_FOUND;
231 return;
232 }
233 params->load_error = GDATA_FILE_OK;
234 }
235
236 // Saves json file content content in |feed| to |file_pathname| on blocking
237 // pool. Used for debugging.
238 void SaveFeedOnBlockingPoolForDebugging(
239 const FilePath& file_path,
240 scoped_ptr<base::Value> feed) {
241 std::string json;
242 base::JSONWriter::WriteWithOptions(feed.get(),
243 base::JSONWriter::OPTIONS_PRETTY_PRINT,
244 &json);
245
246 int file_size = static_cast<int>(json.length());
247 if (file_util::WriteFile(file_path, json.data(), file_size) != file_size) {
248 LOG(WARNING) << "GData metadata file can't be stored at "
249 << file_path.value();
250 if (!file_util::Delete(file_path, true)) {
251 LOG(WARNING) << "GData metadata file can't be deleted at "
252 << file_path.value();
253 return;
254 }
255 }
256 }
257
258 bool UseLevelDB() {
259 return CommandLine::ForCurrentProcess()->HasSwitch(
260 switches::kUseLevelDBForGData);
261 }
262
263 // Gets the file size of |local_file|. 131 // Gets the file size of |local_file|.
264 void GetLocalFileSizeOnBlockingPool(const FilePath& local_file, 132 void GetLocalFileSizeOnBlockingPool(const FilePath& local_file,
265 GDataFileError* error, 133 GDataFileError* error,
266 int64* file_size) { 134 int64* file_size) {
267 DCHECK(error); 135 DCHECK(error);
268 DCHECK(file_size); 136 DCHECK(file_size);
269 137
270 *file_size = 0; 138 *file_size = 0;
271 *error = file_util::GetFileSize(local_file, file_size) ? 139 *error = file_util::GetFileSize(local_file, file_size) ?
272 GDATA_FILE_OK : 140 GDATA_FILE_OK :
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 }; 371 };
504 372
505 // Returns callback which runs the given |callback| on the current thread. 373 // Returns callback which runs the given |callback| on the current thread.
506 template<typename CallbackType> 374 template<typename CallbackType>
507 CallbackType CreateRelayCallback(const CallbackType& callback) { 375 CallbackType CreateRelayCallback(const CallbackType& callback) {
508 return base::Bind(&RelayCallback<CallbackType>::Run, 376 return base::Bind(&RelayCallback<CallbackType>::Run,
509 base::MessageLoopProxy::current(), 377 base::MessageLoopProxy::current(),
510 callback); 378 callback);
511 } 379 }
512 380
513 // Wrapper around BrowserThread::PostTask to post a task to the blocking
514 // pool with the given sequence token.
515 void PostBlockingPoolSequencedTask(
516 const tracked_objects::Location& from_here,
517 base::SequencedTaskRunner* blocking_task_runner,
518 const base::Closure& task) {
519 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
520
521 const bool posted = blocking_task_runner->PostTask(from_here, task);
522 DCHECK(posted);
523 }
524
525 // Similar to PostBlockingPoolSequencedTask() but this one takes a reply
526 // callback that runs on the calling thread.
527 void PostBlockingPoolSequencedTaskAndReply(
528 const tracked_objects::Location& from_here,
529 base::SequencedTaskRunner* blocking_task_runner,
530 const base::Closure& request_task,
531 const base::Closure& reply_task) {
532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
533
534 const bool posted = blocking_task_runner->PostTaskAndReply(
535 from_here, request_task, reply_task);
536 DCHECK(posted);
537 }
538
539 // Helper function for binding |path| to GetEntryInfoWithFilePathCallback and 381 // Helper function for binding |path| to GetEntryInfoWithFilePathCallback and
540 // create GetEntryInfoCallback. 382 // create GetEntryInfoCallback.
541 void RunGetEntryInfoWithFilePathCallback( 383 void RunGetEntryInfoWithFilePathCallback(
542 const GetEntryInfoWithFilePathCallback& callback, 384 const GetEntryInfoWithFilePathCallback& callback,
543 const FilePath& path, 385 const FilePath& path,
544 GDataFileError error, 386 GDataFileError error,
545 scoped_ptr<GDataEntryProto> entry_proto) { 387 scoped_ptr<GDataEntryProto> entry_proto) {
546 if (!callback.is_null()) 388 if (!callback.is_null())
547 callback.Run(error, path, entry_proto.Pass()); 389 callback.Run(error, path, entry_proto.Pass());
548 } 390 }
549 391
550 } // namespace 392 } // namespace
551 393
552 GDataWapiFeedLoader::GDataWapiFeedLoader(
553 GDataDirectoryService* directory_service,
554 DocumentsServiceInterface* documents_service,
555 DriveWebAppsRegistryInterface* webapps_registry,
556 GDataCache* cache,
557 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
558 : directory_service_(directory_service),
559 documents_service_(documents_service),
560 webapps_registry_(webapps_registry),
561 cache_(cache),
562 blocking_task_runner_(blocking_task_runner),
563 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
564 }
565
566 GDataWapiFeedLoader::~GDataWapiFeedLoader() {
567 }
568
569 void GDataWapiFeedLoader::AddObserver(Observer* observer) {
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
571 observers_.AddObserver(observer);
572 }
573
574 void GDataWapiFeedLoader::RemoveObserver(Observer* observer) {
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
576 observers_.RemoveObserver(observer);
577 }
578
579 // Defines set of parameters sent to callback OnNotifyDocumentFeedFetched().
580 // This is a trick to update the number of fetched documents frequently on
581 // UI. Due to performance reason, we need to fetch a number of files at
582 // a time. However, it'll take long time, and a user has no way to know
583 // the current update state. In order to make users confortable,
584 // we increment the number of fetched documents with more frequent but smaller
585 // steps than actual fetching.
586 struct GetDocumentsUiState {
587 explicit GetDocumentsUiState(base::TimeTicks start_time)
588 : num_fetched_documents(0),
589 num_showing_documents(0),
590 start_time(start_time),
591 weak_ptr_factory(this) {
592 }
593
594 // The number of fetched documents.
595 int num_fetched_documents;
596
597 // The number documents shown on UI.
598 int num_showing_documents;
599
600 // When the UI update has started.
601 base::TimeTicks start_time;
602
603 // Time elapsed since the feed fetching was started.
604 base::TimeDelta feed_fetching_elapsed_time;
605
606 base::WeakPtrFactory<GetDocumentsUiState> weak_ptr_factory;
607 };
608
609 // Defines set of parameters sent to callback OnGetDocuments().
610 // TODO(satorux): Move this to a new file: crbug.com/138268
611 struct GetDocumentsParams {
612 GetDocumentsParams(int start_changestamp,
613 int root_feed_changestamp,
614 std::vector<DocumentFeed*>* feed_list,
615 bool should_fetch_multiple_feeds,
616 const FilePath& search_file_path,
617 const std::string& search_query,
618 const std::string& directory_resource_id,
619 const FindEntryCallback& callback,
620 GetDocumentsUiState* ui_state);
621 ~GetDocumentsParams();
622
623 // Changestamps are positive numbers in increasing order. The difference
624 // between two changestamps is proportional equal to number of items in
625 // delta feed between them - bigger the difference, more likely bigger
626 // number of items in delta feeds.
627 int start_changestamp;
628 int root_feed_changestamp;
629 scoped_ptr<std::vector<DocumentFeed*> > feed_list;
630 // Should we stop after getting first feed chunk, even if there is more
631 // data.
632 bool should_fetch_multiple_feeds;
633 FilePath search_file_path;
634 std::string search_query;
635 std::string directory_resource_id;
636 FindEntryCallback callback;
637 scoped_ptr<GetDocumentsUiState> ui_state;
638 };
639
640 GetDocumentsParams::GetDocumentsParams(
641 int start_changestamp,
642 int root_feed_changestamp,
643 std::vector<DocumentFeed*>* feed_list,
644 bool should_fetch_multiple_feeds,
645 const FilePath& search_file_path,
646 const std::string& search_query,
647 const std::string& directory_resource_id,
648 const FindEntryCallback& callback,
649 GetDocumentsUiState* ui_state)
650 : start_changestamp(start_changestamp),
651 root_feed_changestamp(root_feed_changestamp),
652 feed_list(feed_list),
653 should_fetch_multiple_feeds(should_fetch_multiple_feeds),
654 search_file_path(search_file_path),
655 search_query(search_query),
656 directory_resource_id(directory_resource_id),
657 callback(callback),
658 ui_state(ui_state) {
659 }
660
661 GetDocumentsParams::~GetDocumentsParams() {
662 STLDeleteElements(feed_list.get());
663 }
664
665 // GDataFileSystem::CreateDirectoryParams struct implementation. 394 // GDataFileSystem::CreateDirectoryParams struct implementation.
666 struct GDataFileSystem::CreateDirectoryParams { 395 struct GDataFileSystem::CreateDirectoryParams {
667 CreateDirectoryParams(const FilePath& created_directory_path, 396 CreateDirectoryParams(const FilePath& created_directory_path,
668 const FilePath& target_directory_path, 397 const FilePath& target_directory_path,
669 bool is_exclusive, 398 bool is_exclusive,
670 bool is_recursive, 399 bool is_recursive,
671 const FileOperationCallback& callback); 400 const FileOperationCallback& callback);
672 ~CreateDirectoryParams(); 401 ~CreateDirectoryParams();
673 402
674 const FilePath created_directory_path; 403 const FilePath created_directory_path;
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 } 697 }
969 698
970 void GDataFileSystem::FindEntryByPathSyncOnUIThread( 699 void GDataFileSystem::FindEntryByPathSyncOnUIThread(
971 const FilePath& search_file_path, 700 const FilePath& search_file_path,
972 const FindEntryCallback& callback) { 701 const FindEntryCallback& callback) {
973 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
974 703
975 directory_service_->FindEntryByPathAndRunSync(search_file_path, callback); 704 directory_service_->FindEntryByPathAndRunSync(search_file_path, callback);
976 } 705 }
977 706
978 void GDataWapiFeedLoader::ReloadFromServerIfNeeded(
979 ContentOrigin initial_origin,
980 int local_changestamp,
981 const FilePath& search_file_path,
982 const FindEntryCallback& callback) {
983 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
984
985 DVLOG(1) << "ReloadFeedFromServerIfNeeded local_changestamp="
986 << local_changestamp << ", initial_origin=" << initial_origin;
987
988 // First fetch the latest changestamp to see if there were any new changes
989 // there at all.
990 documents_service_->GetAccountMetadata(
991 base::Bind(&GDataWapiFeedLoader::OnGetAccountMetadata,
992 weak_ptr_factory_.GetWeakPtr(),
993 initial_origin,
994 local_changestamp,
995 search_file_path,
996 callback));
997 }
998
999 void GDataWapiFeedLoader::OnGetAccountMetadata(
1000 ContentOrigin initial_origin,
1001 int local_changestamp,
1002 const FilePath& search_file_path,
1003 const FindEntryCallback& callback,
1004 GDataErrorCode status,
1005 scoped_ptr<base::Value> feed_data) {
1006 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1007
1008 GDataFileError error = GDataToGDataFileError(status);
1009 if (error != GDATA_FILE_OK) {
1010 // Get changes starting from the next changestamp from what we have locally.
1011 LoadFromServer(initial_origin,
1012 local_changestamp + 1, 0,
1013 true, /* should_fetch_multiple_feeds */
1014 search_file_path,
1015 std::string() /* no search query */,
1016 GURL(), /* feed not explicitly set */
1017 std::string() /* no directory resource ID */,
1018 callback,
1019 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded,
1020 weak_ptr_factory_.GetWeakPtr()));
1021 return;
1022 }
1023
1024 scoped_ptr<AccountMetadataFeed> account_metadata;
1025 if (feed_data.get()) {
1026 account_metadata = AccountMetadataFeed::CreateFrom(*feed_data);
1027 #ifndef NDEBUG
1028 // Save account metadata feed for analysis.
1029 const FilePath path =
1030 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append(
1031 kAccountMetadataFile);
1032 PostBlockingPoolSequencedTask(
1033 FROM_HERE,
1034 blocking_task_runner_,
1035 base::Bind(&SaveFeedOnBlockingPoolForDebugging,
1036 path, base::Passed(&feed_data)));
1037 #endif
1038 }
1039
1040 if (!account_metadata.get()) {
1041 LoadFromServer(initial_origin,
1042 local_changestamp + 1, 0,
1043 true, /* should_fetch_multiple_feeds */
1044 search_file_path,
1045 std::string() /* no search query */,
1046 GURL(), /* feed not explicitly set */
1047 std::string() /* no directory resource ID */,
1048 callback,
1049 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded,
1050 weak_ptr_factory_.GetWeakPtr()));
1051 return;
1052 }
1053
1054 webapps_registry_->UpdateFromFeed(account_metadata.get());
1055
1056 bool changes_detected = true;
1057 if (local_changestamp >= account_metadata->largest_changestamp()) {
1058 if (local_changestamp > account_metadata->largest_changestamp()) {
1059 LOG(WARNING) << "Cached client feed is fresher than server, client = "
1060 << local_changestamp
1061 << ", server = "
1062 << account_metadata->largest_changestamp();
1063 }
1064 // If our cache holds the latest state from the server, change the
1065 // state to FROM_SERVER.
1066 directory_service_->set_origin(
1067 initial_origin == FROM_CACHE ? FROM_SERVER : initial_origin);
1068 changes_detected = false;
1069 }
1070
1071 // No changes detected, continue with search as planned.
1072 if (!changes_detected) {
1073 if (!callback.is_null()) {
1074 directory_service_->FindEntryByPathAndRunSync(search_file_path,
1075 callback);
1076 }
1077 return;
1078 }
1079
1080 // Load changes from the server.
1081 LoadFromServer(initial_origin,
1082 local_changestamp > 0 ? local_changestamp + 1 : 0,
1083 account_metadata->largest_changestamp(),
1084 true, /* should_fetch_multiple_feeds */
1085 search_file_path,
1086 std::string() /* no search query */,
1087 GURL(), /* feed not explicitly set */
1088 std::string() /* no directory resource ID */,
1089 callback,
1090 base::Bind(&GDataWapiFeedLoader::OnFeedFromServerLoaded,
1091 weak_ptr_factory_.GetWeakPtr()));
1092 }
1093
1094 void GDataWapiFeedLoader::LoadFromServer(
1095 ContentOrigin initial_origin,
1096 int start_changestamp,
1097 int root_feed_changestamp,
1098 bool should_fetch_multiple_feeds,
1099 const FilePath& search_file_path,
1100 const std::string& search_query,
1101 const GURL& feed_to_load,
1102 const std::string& directory_resource_id,
1103 const FindEntryCallback& entry_found_callback,
1104 const LoadDocumentFeedCallback& feed_load_callback) {
1105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1106
1107 // |feed_list| will contain the list of all collected feed updates that
1108 // we will receive through calls of DocumentsService::GetDocuments().
1109 scoped_ptr<std::vector<DocumentFeed*> > feed_list(
1110 new std::vector<DocumentFeed*>);
1111 const base::TimeTicks start_time = base::TimeTicks::Now();
1112 documents_service_->GetDocuments(
1113 feed_to_load,
1114 start_changestamp,
1115 search_query,
1116 directory_resource_id,
1117 base::Bind(&GDataWapiFeedLoader::OnGetDocuments,
1118 weak_ptr_factory_.GetWeakPtr(),
1119 initial_origin,
1120 feed_load_callback,
1121 base::Owned(new GetDocumentsParams(start_changestamp,
1122 root_feed_changestamp,
1123 feed_list.release(),
1124 should_fetch_multiple_feeds,
1125 search_file_path,
1126 search_query,
1127 directory_resource_id,
1128 entry_found_callback,
1129 NULL)),
1130 start_time));
1131 }
1132
1133 void GDataWapiFeedLoader::OnFeedFromServerLoaded(GetDocumentsParams* params,
1134 GDataFileError error) {
1135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1136
1137 if (error != GDATA_FILE_OK) {
1138 if (!params->callback.is_null())
1139 params->callback.Run(error, NULL);
1140 return;
1141 }
1142
1143 error = UpdateFromFeed(*params->feed_list,
1144 params->start_changestamp,
1145 params->root_feed_changestamp);
1146
1147 if (error != GDATA_FILE_OK) {
1148 if (!params->callback.is_null())
1149 params->callback.Run(error, NULL);
1150
1151 return;
1152 }
1153
1154 // Save file system metadata to disk.
1155 SaveFileSystem();
1156
1157 // If we had someone to report this too, then this retrieval was done in a
1158 // context of search... so continue search.
1159 if (!params->callback.is_null()) {
1160 directory_service_->FindEntryByPathAndRunSync(params->search_file_path,
1161 params->callback);
1162 }
1163
1164 FOR_EACH_OBSERVER(Observer, observers_, OnFeedFromServerLoaded());
1165 }
1166
1167 void GDataFileSystem::TransferFileFromRemoteToLocal( 707 void GDataFileSystem::TransferFileFromRemoteToLocal(
1168 const FilePath& remote_src_file_path, 708 const FilePath& remote_src_file_path,
1169 const FilePath& local_dest_file_path, 709 const FilePath& local_dest_file_path,
1170 const FileOperationCallback& callback) { 710 const FileOperationCallback& callback) {
1171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 711 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1172 712
1173 GetFileByPath(remote_src_file_path, 713 GetFileByPath(remote_src_file_path,
1174 base::Bind(&GDataFileSystem::OnGetFileCompleteForTransferFile, 714 base::Bind(&GDataFileSystem::OnGetFileCompleteForTransferFile,
1175 ui_weak_ptr_, 715 ui_weak_ptr_,
1176 local_dest_file_path, 716 local_dest_file_path,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 if (!entry_proto->file_info().is_directory()) { 755 if (!entry_proto->file_info().is_directory()) {
1216 // The parent of |remote_dest_file_path| is not a directory. 756 // The parent of |remote_dest_file_path| is not a directory.
1217 if (!callback.is_null()) { 757 if (!callback.is_null()) {
1218 base::MessageLoopProxy::current()->PostTask( 758 base::MessageLoopProxy::current()->PostTask(
1219 FROM_HERE, base::Bind(callback, GDATA_FILE_ERROR_NOT_A_DIRECTORY)); 759 FROM_HERE, base::Bind(callback, GDATA_FILE_ERROR_NOT_A_DIRECTORY));
1220 } 760 }
1221 return; 761 return;
1222 } 762 }
1223 763
1224 std::string* resource_id = new std::string; 764 std::string* resource_id = new std::string;
1225 PostBlockingPoolSequencedTaskAndReply( 765 util::PostBlockingPoolSequencedTaskAndReply(
1226 FROM_HERE, 766 FROM_HERE,
1227 blocking_task_runner_, 767 blocking_task_runner_,
1228 base::Bind(&GetDocumentResourceIdOnBlockingPool, 768 base::Bind(&GetDocumentResourceIdOnBlockingPool,
1229 local_src_file_path, 769 local_src_file_path,
1230 resource_id), 770 resource_id),
1231 base::Bind(&GDataFileSystem::TransferFileForResourceId, 771 base::Bind(&GDataFileSystem::TransferFileForResourceId,
1232 ui_weak_ptr_, 772 ui_weak_ptr_,
1233 local_src_file_path, 773 local_src_file_path,
1234 remote_dest_file_path, 774 remote_dest_file_path,
1235 callback, 775 callback,
(...skipping 28 matching lines...) Expand all
1264 void GDataFileSystem::TransferRegularFile( 804 void GDataFileSystem::TransferRegularFile(
1265 const FilePath& local_file_path, 805 const FilePath& local_file_path,
1266 const FilePath& remote_dest_file_path, 806 const FilePath& remote_dest_file_path,
1267 const FileOperationCallback& callback) { 807 const FileOperationCallback& callback) {
1268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 808 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1269 809
1270 GDataFileError* error = 810 GDataFileError* error =
1271 new GDataFileError(GDATA_FILE_OK); 811 new GDataFileError(GDATA_FILE_OK);
1272 int64* file_size = new int64; 812 int64* file_size = new int64;
1273 std::string* content_type = new std::string; 813 std::string* content_type = new std::string;
1274 PostBlockingPoolSequencedTaskAndReply( 814 util::PostBlockingPoolSequencedTaskAndReply(
1275 FROM_HERE, 815 FROM_HERE,
1276 blocking_task_runner_, 816 blocking_task_runner_,
1277 base::Bind(&GetLocalFileInfoOnBlockingPool, 817 base::Bind(&GetLocalFileInfoOnBlockingPool,
1278 local_file_path, 818 local_file_path,
1279 error, 819 error,
1280 file_size, 820 file_size,
1281 content_type), 821 content_type),
1282 base::Bind(&GDataFileSystem::StartFileUploadOnUIThread, 822 base::Bind(&GDataFileSystem::StartFileUploadOnUIThread,
1283 ui_weak_ptr_, 823 ui_weak_ptr_,
1284 StartFileUploadParams(local_file_path, 824 StartFileUploadParams(local_file_path,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 callback.Run(error); 1032 callback.Run(error);
1493 1033
1494 return; 1034 return;
1495 } 1035 }
1496 1036
1497 // GetFileByPath downloads the file from gdata to a local cache, which is then 1037 // GetFileByPath downloads the file from gdata to a local cache, which is then
1498 // copied to the actual destination path on the local file system using 1038 // copied to the actual destination path on the local file system using
1499 // CopyLocalFileOnBlockingPool. 1039 // CopyLocalFileOnBlockingPool.
1500 GDataFileError* copy_file_error = 1040 GDataFileError* copy_file_error =
1501 new GDataFileError(GDATA_FILE_OK); 1041 new GDataFileError(GDATA_FILE_OK);
1502 PostBlockingPoolSequencedTaskAndReply( 1042 util::PostBlockingPoolSequencedTaskAndReply(
1503 FROM_HERE, 1043 FROM_HERE,
1504 blocking_task_runner_, 1044 blocking_task_runner_,
1505 base::Bind(&CopyLocalFileOnBlockingPool, 1045 base::Bind(&CopyLocalFileOnBlockingPool,
1506 local_file_path, 1046 local_file_path,
1507 local_dest_file_path, 1047 local_dest_file_path,
1508 copy_file_error), 1048 copy_file_error),
1509 base::Bind(&RunFileOperationCallbackHelper, 1049 base::Bind(&RunFileOperationCallbackHelper,
1510 callback, 1050 callback,
1511 base::Owned(copy_file_error))); 1051 base::Owned(copy_file_error)));
1512 } 1052 }
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 // For a hosted document, we create a special JSON file to represent the 1555 // For a hosted document, we create a special JSON file to represent the
2016 // document instead of fetching the document content in one of the exported 1556 // document instead of fetching the document content in one of the exported
2017 // formats. The JSON file contains the edit URL and resource ID of the 1557 // formats. The JSON file contains the edit URL and resource ID of the
2018 // document. 1558 // document.
2019 if (entry_proto->file_specific_info().is_hosted_document()) { 1559 if (entry_proto->file_specific_info().is_hosted_document()) {
2020 GDataFileError* error = 1560 GDataFileError* error =
2021 new GDataFileError(GDATA_FILE_OK); 1561 new GDataFileError(GDATA_FILE_OK);
2022 FilePath* temp_file_path = new FilePath; 1562 FilePath* temp_file_path = new FilePath;
2023 std::string* mime_type = new std::string; 1563 std::string* mime_type = new std::string;
2024 GDataFileType* file_type = new GDataFileType(REGULAR_FILE); 1564 GDataFileType* file_type = new GDataFileType(REGULAR_FILE);
2025 PostBlockingPoolSequencedTaskAndReply( 1565 util::PostBlockingPoolSequencedTaskAndReply(
2026 FROM_HERE, 1566 FROM_HERE,
2027 blocking_task_runner_, 1567 blocking_task_runner_,
2028 base::Bind(&CreateDocumentJsonFileOnBlockingPool, 1568 base::Bind(&CreateDocumentJsonFileOnBlockingPool,
2029 cache_->GetCacheDirectoryPath( 1569 cache_->GetCacheDirectoryPath(
2030 GDataCache::CACHE_TYPE_TMP_DOCUMENTS), 1570 GDataCache::CACHE_TYPE_TMP_DOCUMENTS),
2031 GURL(entry_proto->file_specific_info().alternate_url()), 1571 GURL(entry_proto->file_specific_info().alternate_url()),
2032 entry_proto->resource_id(), 1572 entry_proto->resource_id(),
2033 error, 1573 error,
2034 temp_file_path, 1574 temp_file_path,
2035 mime_type, 1575 mime_type,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 params.get_file_callback, 1707 params.get_file_callback,
2168 params.get_download_data_callback))); 1708 params.get_download_data_callback)));
2169 } 1709 }
2170 1710
2171 void GDataFileSystem::OnGetDocumentEntry(const FilePath& cache_file_path, 1711 void GDataFileSystem::OnGetDocumentEntry(const FilePath& cache_file_path,
2172 const GetFileFromCacheParams& params, 1712 const GetFileFromCacheParams& params,
2173 GDataErrorCode status, 1713 GDataErrorCode status,
2174 scoped_ptr<base::Value> data) { 1714 scoped_ptr<base::Value> data) {
2175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2176 1716
2177 GDataFileError error = GDataToGDataFileError(status); 1717 GDataFileError error = util::GDataToGDataFileError(status);
2178 1718
2179 scoped_ptr<GDataEntry> fresh_entry; 1719 scoped_ptr<GDataEntry> fresh_entry;
2180 if (error == GDATA_FILE_OK) { 1720 if (error == GDATA_FILE_OK) {
2181 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data)); 1721 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data));
2182 if (doc_entry.get()) { 1722 if (doc_entry.get()) {
2183 fresh_entry.reset( 1723 fresh_entry.reset(
2184 GDataEntry::FromDocumentEntry(NULL, doc_entry.get(), 1724 GDataEntry::FromDocumentEntry(NULL, doc_entry.get(),
2185 directory_service_.get())); 1725 directory_service_.get()));
2186 } 1726 }
2187 if (!fresh_entry.get() || !fresh_entry->AsGDataFile()) { 1727 if (!fresh_entry.get() || !fresh_entry->AsGDataFile()) {
(...skipping 14 matching lines...) Expand all
2202 1742
2203 GURL content_url = fresh_entry->content_url(); 1743 GURL content_url = fresh_entry->content_url();
2204 int64 file_size = fresh_entry->file_info().size; 1744 int64 file_size = fresh_entry->file_info().size;
2205 1745
2206 DCHECK_EQ(params.resource_id, fresh_entry->resource_id()); 1746 DCHECK_EQ(params.resource_id, fresh_entry->resource_id());
2207 scoped_ptr<GDataFile> fresh_entry_as_file( 1747 scoped_ptr<GDataFile> fresh_entry_as_file(
2208 fresh_entry.release()->AsGDataFile()); 1748 fresh_entry.release()->AsGDataFile());
2209 directory_service_->RefreshFile(fresh_entry_as_file.Pass()); 1749 directory_service_->RefreshFile(fresh_entry_as_file.Pass());
2210 1750
2211 bool* has_enough_space = new bool(false); 1751 bool* has_enough_space = new bool(false);
2212 PostBlockingPoolSequencedTaskAndReply( 1752 util::PostBlockingPoolSequencedTaskAndReply(
2213 FROM_HERE, 1753 FROM_HERE,
2214 blocking_task_runner_, 1754 blocking_task_runner_,
2215 base::Bind(&GDataCache::FreeDiskSpaceIfNeededFor, 1755 base::Bind(&GDataCache::FreeDiskSpaceIfNeededFor,
2216 base::Unretained(cache_), 1756 base::Unretained(cache_),
2217 file_size, 1757 file_size,
2218 has_enough_space), 1758 has_enough_space),
2219 base::Bind(&GDataFileSystem::StartDownloadFileIfEnoughSpace, 1759 base::Bind(&GDataFileSystem::StartDownloadFileIfEnoughSpace,
2220 ui_weak_ptr_, 1760 ui_weak_ptr_,
2221 params, 1761 params,
2222 content_url, 1762 content_url,
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 if (error != GDATA_FILE_OK) { 2075 if (error != GDATA_FILE_OK) {
2536 if (!callback.is_null()) 2076 if (!callback.is_null())
2537 callback.Run(error); 2077 callback.Run(error);
2538 return; 2078 return;
2539 } 2079 }
2540 2080
2541 // Gets the size of the cache file. Since the file is locally modified, the 2081 // Gets the size of the cache file. Since the file is locally modified, the
2542 // file size information stored in GDataEntry is not correct. 2082 // file size information stored in GDataEntry is not correct.
2543 GDataFileError* get_size_error = new GDataFileError(GDATA_FILE_ERROR_FAILED); 2083 GDataFileError* get_size_error = new GDataFileError(GDATA_FILE_ERROR_FAILED);
2544 int64* file_size = new int64(-1); 2084 int64* file_size = new int64(-1);
2545 PostBlockingPoolSequencedTaskAndReply( 2085 util::PostBlockingPoolSequencedTaskAndReply(
2546 FROM_HERE, 2086 FROM_HERE,
2547 blocking_task_runner_, 2087 blocking_task_runner_,
2548 base::Bind(&GetLocalFileSizeOnBlockingPool, 2088 base::Bind(&GetLocalFileSizeOnBlockingPool,
2549 cache_file_path, 2089 cache_file_path,
2550 get_size_error, 2090 get_size_error,
2551 file_size), 2091 file_size),
2552 base::Bind(&GDataFileSystem::OnGetFileSizeCompleteForUpdateFile, 2092 base::Bind(&GDataFileSystem::OnGetFileSizeCompleteForUpdateFile,
2553 ui_weak_ptr_, 2093 ui_weak_ptr_,
2554 callback, 2094 callback,
2555 resource_id, 2095 resource_id,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 ui_weak_ptr_, 2188 ui_weak_ptr_,
2649 callback)); 2189 callback));
2650 } 2190 }
2651 2191
2652 void GDataFileSystem::OnGetAvailableSpace( 2192 void GDataFileSystem::OnGetAvailableSpace(
2653 const GetAvailableSpaceCallback& callback, 2193 const GetAvailableSpaceCallback& callback,
2654 GDataErrorCode status, 2194 GDataErrorCode status,
2655 scoped_ptr<base::Value> data) { 2195 scoped_ptr<base::Value> data) {
2656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2657 2197
2658 GDataFileError error = GDataToGDataFileError(status); 2198 GDataFileError error = util::GDataToGDataFileError(status);
2659 if (error != GDATA_FILE_OK) { 2199 if (error != GDATA_FILE_OK) {
2660 callback.Run(error, -1, -1); 2200 callback.Run(error, -1, -1);
2661 return; 2201 return;
2662 } 2202 }
2663 2203
2664 scoped_ptr<AccountMetadataFeed> feed; 2204 scoped_ptr<AccountMetadataFeed> feed;
2665 if (data.get()) 2205 if (data.get())
2666 feed = AccountMetadataFeed::CreateFrom(*data); 2206 feed = AccountMetadataFeed::CreateFrom(*data);
2667 if (!feed.get()) { 2207 if (!feed.get()) {
2668 callback.Run(GDATA_FILE_ERROR_FAILED, -1, -1); 2208 callback.Run(GDATA_FILE_ERROR_FAILED, -1, -1);
2669 return; 2209 return;
2670 } 2210 }
2671 2211
2672 callback.Run(GDATA_FILE_OK, 2212 callback.Run(GDATA_FILE_OK,
2673 feed->quota_bytes_total(), 2213 feed->quota_bytes_total(),
2674 feed->quota_bytes_used()); 2214 feed->quota_bytes_used());
2675 } 2215 }
2676 2216
2677 void GDataFileSystem::OnCreateDirectoryCompleted( 2217 void GDataFileSystem::OnCreateDirectoryCompleted(
2678 const CreateDirectoryParams& params, 2218 const CreateDirectoryParams& params,
2679 GDataErrorCode status, 2219 GDataErrorCode status,
2680 scoped_ptr<base::Value> data) { 2220 scoped_ptr<base::Value> data) {
2681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2682 2222
2683 GDataFileError error = GDataToGDataFileError(status); 2223 GDataFileError error = util::GDataToGDataFileError(status);
2684 if (error != GDATA_FILE_OK) { 2224 if (error != GDATA_FILE_OK) {
2685 if (!params.callback.is_null()) 2225 if (!params.callback.is_null())
2686 params.callback.Run(error); 2226 params.callback.Run(error);
2687 2227
2688 return; 2228 return;
2689 } 2229 }
2690 2230
2691 base::DictionaryValue* dict_value = NULL; 2231 base::DictionaryValue* dict_value = NULL;
2692 base::Value* created_entry = NULL; 2232 base::Value* created_entry = NULL;
2693 if (data.get() && data->GetAsDictionary(&dict_value) && dict_value) 2233 if (data.get() && data->GetAsDictionary(&dict_value) && dict_value)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2815 // chunk to avoid displaying huge number of search 2355 // chunk to avoid displaying huge number of search
2816 // results (especially since we don't cache them). 2356 // results (especially since we don't cache them).
2817 FilePath(), // Not used. 2357 FilePath(), // Not used.
2818 search_query, 2358 search_query,
2819 next_feed, 2359 next_feed,
2820 std::string(), // No directory resource ID. 2360 std::string(), // No directory resource ID.
2821 FindEntryCallback(), // Not used. 2361 FindEntryCallback(), // Not used.
2822 base::Bind(&GDataFileSystem::OnSearch, ui_weak_ptr_, callback)); 2362 base::Bind(&GDataFileSystem::OnSearch, ui_weak_ptr_, callback));
2823 } 2363 }
2824 2364
2825 void GDataWapiFeedLoader::OnGetDocuments(
2826 ContentOrigin initial_origin,
2827 const LoadDocumentFeedCallback& callback,
2828 GetDocumentsParams* params,
2829 base::TimeTicks start_time,
2830 GDataErrorCode status,
2831 scoped_ptr<base::Value> data) {
2832 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2833
2834 if (params->feed_list->empty()) {
2835 UMA_HISTOGRAM_TIMES("Gdata.InitialFeedLoadTime",
2836 base::TimeTicks::Now() - start_time);
2837 }
2838
2839 GDataFileError error = GDataToGDataFileError(status);
2840 if (error == GDATA_FILE_OK &&
2841 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) {
2842 error = GDATA_FILE_ERROR_FAILED;
2843 }
2844
2845 if (error != GDATA_FILE_OK) {
2846 directory_service_->set_origin(initial_origin);
2847
2848 if (!callback.is_null())
2849 callback.Run(params, error);
2850
2851 return;
2852 }
2853
2854 GURL next_feed_url;
2855 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data));
2856 if (!current_feed.get()) {
2857 if (!callback.is_null()) {
2858 callback.Run(params, GDATA_FILE_ERROR_FAILED);
2859 }
2860
2861 return;
2862 }
2863 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url);
2864
2865 #ifndef NDEBUG
2866 // Save initial root feed for analysis.
2867 std::string file_name =
2868 base::StringPrintf("DEBUG_feed_%d.json",
2869 params->start_changestamp);
2870 PostBlockingPoolSequencedTask(
2871 FROM_HERE,
2872 blocking_task_runner_,
2873 base::Bind(&SaveFeedOnBlockingPoolForDebugging,
2874 cache_->GetCacheDirectoryPath(
2875 GDataCache::CACHE_TYPE_META).Append(file_name),
2876 base::Passed(&data)));
2877 #endif
2878
2879 // Add the current feed to the list of collected feeds for this directory.
2880 params->feed_list->push_back(current_feed.release());
2881
2882 // Compute and notify the number of entries fetched so far.
2883 int num_accumulated_entries = 0;
2884 for (size_t i = 0; i < params->feed_list->size(); ++i)
2885 num_accumulated_entries += params->feed_list->at(i)->entries().size();
2886
2887 // Check if we need to collect more data to complete the directory list.
2888 if (params->should_fetch_multiple_feeds && has_next_feed_url &&
2889 !next_feed_url.is_empty()) {
2890 // Post an UI update event to make the UI smoother.
2891 GetDocumentsUiState* ui_state = params->ui_state.get();
2892 if (ui_state == NULL) {
2893 ui_state = new GetDocumentsUiState(base::TimeTicks::Now());
2894 params->ui_state.reset(ui_state);
2895 }
2896 DCHECK(ui_state);
2897
2898 if ((ui_state->num_fetched_documents - ui_state->num_showing_documents)
2899 < kFetchUiUpdateStep) {
2900 // Currently the UI update is stopped. Start UI periodic callback.
2901 MessageLoop::current()->PostTask(
2902 FROM_HERE,
2903 base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched,
2904 weak_ptr_factory_.GetWeakPtr(),
2905 ui_state->weak_ptr_factory.GetWeakPtr()));
2906 }
2907 ui_state->num_fetched_documents = num_accumulated_entries;
2908 ui_state->feed_fetching_elapsed_time = base::TimeTicks::Now() - start_time;
2909
2910 // Kick of the remaining part of the feeds.
2911 documents_service_->GetDocuments(
2912 next_feed_url,
2913 params->start_changestamp,
2914 params->search_query,
2915 params->directory_resource_id,
2916 base::Bind(&GDataWapiFeedLoader::OnGetDocuments,
2917 weak_ptr_factory_.GetWeakPtr(),
2918 initial_origin,
2919 callback,
2920 base::Owned(
2921 new GetDocumentsParams(
2922 params->start_changestamp,
2923 params->root_feed_changestamp,
2924 params->feed_list.release(),
2925 params->should_fetch_multiple_feeds,
2926 params->search_file_path,
2927 params->search_query,
2928 params->directory_resource_id,
2929 params->callback,
2930 params->ui_state.release())),
2931 start_time));
2932 return;
2933 }
2934
2935 // Notify the observers that a document feed is fetched.
2936 FOR_EACH_OBSERVER(Observer, observers_,
2937 OnDocumentFeedFetched(num_accumulated_entries));
2938
2939 UMA_HISTOGRAM_TIMES("Gdata.EntireFeedLoadTime",
2940 base::TimeTicks::Now() - start_time);
2941
2942 if (!callback.is_null())
2943 callback.Run(params, error);
2944 }
2945
2946 void GDataWapiFeedLoader::OnNotifyDocumentFeedFetched(
2947 base::WeakPtr<GetDocumentsUiState> ui_state) {
2948 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2949
2950 if (!ui_state) {
2951 // The ui state instance is already released, which means the fetching
2952 // is done and we don't need to update any more.
2953 return;
2954 }
2955
2956 base::TimeDelta elapsed_time =
2957 base::TimeTicks::Now() - ui_state->start_time;
2958
2959 if (ui_state->num_showing_documents + kFetchUiUpdateStep <=
2960 ui_state->num_fetched_documents) {
2961 ui_state->num_showing_documents += kFetchUiUpdateStep;
2962 FOR_EACH_OBSERVER(Observer, observers_,
2963 OnDocumentFeedFetched(ui_state->num_showing_documents));
2964
2965 int num_remaining_ui_updates =
2966 (ui_state->num_fetched_documents - ui_state->num_showing_documents)
2967 / kFetchUiUpdateStep;
2968 if (num_remaining_ui_updates > 0) {
2969 // Heuristically, we use fetched time duration to calculate the next
2970 // UI update timing.
2971 base::TimeDelta remaining_duration =
2972 ui_state->feed_fetching_elapsed_time - elapsed_time;
2973 MessageLoop::current()->PostDelayedTask(
2974 FROM_HERE,
2975 base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched,
2976 weak_ptr_factory_.GetWeakPtr(),
2977 ui_state->weak_ptr_factory.GetWeakPtr()),
2978 remaining_duration / num_remaining_ui_updates);
2979 }
2980 }
2981 }
2982
2983 void GDataWapiFeedLoader::LoadFromCache(
2984 bool should_load_from_server,
2985 const FilePath& search_file_path,
2986 const FindEntryCallback& callback) {
2987 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2988
2989 LoadRootFeedParams* params = new LoadRootFeedParams(search_file_path,
2990 should_load_from_server,
2991 callback);
2992 FilePath path = cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META);
2993 if (UseLevelDB()) {
2994 path = path.Append(kResourceMetadataDBFile);
2995 directory_service_->InitFromDB(path, blocking_task_runner_,
2996 base::Bind(
2997 &GDataWapiFeedLoader::ContinueWithInitializedDirectoryService,
2998 weak_ptr_factory_.GetWeakPtr(),
2999 base::Owned(params)));
3000 } else {
3001 path = path.Append(kFilesystemProtoFile);
3002 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE,
3003 base::Bind(&LoadProtoOnBlockingPool, path, params),
3004 base::Bind(&GDataWapiFeedLoader::OnProtoLoaded,
3005 weak_ptr_factory_.GetWeakPtr(),
3006 base::Owned(params)));
3007 }
3008 }
3009
3010 void GDataFileSystem::OnDirectoryChanged(const FilePath& directory_path) { 2365 void GDataFileSystem::OnDirectoryChanged(const FilePath& directory_path) {
3011 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3012 2367
3013 FOR_EACH_OBSERVER(GDataFileSystemInterface::Observer, observers_, 2368 FOR_EACH_OBSERVER(GDataFileSystemInterface::Observer, observers_,
3014 OnDirectoryChanged(directory_path)); 2369 OnDirectoryChanged(directory_path));
3015 } 2370 }
3016 2371
3017 void GDataFileSystem::OnDocumentFeedFetched(int num_accumulated_entries) { 2372 void GDataFileSystem::OnDocumentFeedFetched(int num_accumulated_entries) {
3018 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3019 2374
(...skipping 22 matching lines...) Expand all
3042 const std::vector<DocumentFeed*>& feed_list, 2397 const std::vector<DocumentFeed*>& feed_list,
3043 int start_changestamp, 2398 int start_changestamp,
3044 int root_feed_changestamp) { 2399 int root_feed_changestamp) {
3045 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3046 2401
3047 return feed_loader_->UpdateFromFeed(feed_list, 2402 return feed_loader_->UpdateFromFeed(feed_list,
3048 start_changestamp, 2403 start_changestamp,
3049 root_feed_changestamp); 2404 root_feed_changestamp);
3050 } 2405 }
3051 2406
3052 void GDataWapiFeedLoader::OnProtoLoaded(LoadRootFeedParams* params) {
3053 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3054
3055 // If we have already received updates from the server, bail out.
3056 if (directory_service_->origin() == FROM_SERVER)
3057 return;
3058
3059 // Update directory structure only if everything is OK and we haven't yet
3060 // received the feed from the server yet.
3061 if (params->load_error == GDATA_FILE_OK) {
3062 DVLOG(1) << "ParseFromString";
3063 if (directory_service_->ParseFromString(params->proto)) {
3064 directory_service_->set_last_serialized(params->last_modified);
3065 directory_service_->set_serialized_size(params->proto.size());
3066 } else {
3067 params->load_error = GDATA_FILE_ERROR_FAILED;
3068 LOG(WARNING) << "Parse of cached proto file failed";
3069 }
3070 }
3071
3072 ContinueWithInitializedDirectoryService(params, params->load_error);
3073 }
3074
3075 void GDataWapiFeedLoader::ContinueWithInitializedDirectoryService(
3076 LoadRootFeedParams* params,
3077 GDataFileError error) {
3078 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3079
3080 DVLOG(1) << "Time elapsed to load directory service from disk="
3081 << (base::Time::Now() - params->load_start_time).InMilliseconds()
3082 << " milliseconds";
3083
3084 FindEntryCallback callback = params->callback;
3085 // If we got feed content from cache, try search over it.
3086 if (error == GDATA_FILE_OK && !callback.is_null()) {
3087 // Continue file content search operation if the delegate hasn't terminated
3088 // this search branch already.
3089 directory_service_->FindEntryByPathAndRunSync(params->search_file_path,
3090 callback);
3091 callback.Reset();
3092 }
3093
3094 if (!params->should_load_from_server)
3095 return;
3096
3097 // Decide the |initial_origin| to pass to ReloadFromServerIfNeeded().
3098 // This is used to restore directory content origin to its initial value when
3099 // we fail to retrieve the feed from server.
3100 // By default, if directory content is not yet initialized, restore content
3101 // origin to UNINITIALIZED in case of failure.
3102 ContentOrigin initial_origin = UNINITIALIZED;
3103 if (directory_service_->origin() != INITIALIZING) {
3104 // If directory content is already initialized, restore content origin
3105 // to FROM_CACHE in case of failure.
3106 initial_origin = FROM_CACHE;
3107 directory_service_->set_origin(REFRESHING);
3108 }
3109
3110 // Kick of the retrieval of the feed from server. If we have previously
3111 // |reported| to the original callback, then we just need to refresh the
3112 // content without continuing search upon operation completion.
3113 ReloadFromServerIfNeeded(initial_origin,
3114 directory_service_->largest_changestamp(),
3115 params->search_file_path,
3116 callback);
3117 }
3118
3119 void GDataWapiFeedLoader::SaveFileSystem() {
3120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3121
3122 if (!ShouldSerializeFileSystemNow(directory_service_->serialized_size(),
3123 directory_service_->last_serialized())) {
3124 return;
3125 }
3126
3127 if (UseLevelDB()) {
3128 directory_service_->SaveToDB();
3129 } else {
3130 const FilePath path =
3131 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append(
3132 kFilesystemProtoFile);
3133 scoped_ptr<std::string> serialized_proto(new std::string());
3134 directory_service_->SerializeToString(serialized_proto.get());
3135 directory_service_->set_last_serialized(base::Time::Now());
3136 directory_service_->set_serialized_size(serialized_proto->size());
3137 PostBlockingPoolSequencedTask(
3138 FROM_HERE,
3139 blocking_task_runner_,
3140 base::Bind(&SaveProtoOnBlockingPool, path,
3141 base::Passed(serialized_proto.Pass())));
3142 }
3143 }
3144
3145 void GDataFileSystem::OnFilePathUpdated(const FileOperationCallback& callback, 2407 void GDataFileSystem::OnFilePathUpdated(const FileOperationCallback& callback,
3146 GDataFileError error, 2408 GDataFileError error,
3147 const FilePath& file_path) { 2409 const FilePath& file_path) {
3148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3149 if (!callback.is_null()) 2411 if (!callback.is_null())
3150 callback.Run(error); 2412 callback.Run(error);
3151 } 2413 }
3152 2414
3153 void GDataFileSystem::OnRenameResourceCompleted( 2415 void GDataFileSystem::OnRenameResourceCompleted(
3154 const FilePath& file_path, 2416 const FilePath& file_path,
3155 const FilePath::StringType& new_name, 2417 const FilePath::StringType& new_name,
3156 const FilePathUpdateCallback& callback, 2418 const FilePathUpdateCallback& callback,
3157 GDataErrorCode status, 2419 GDataErrorCode status,
3158 const GURL& document_url) { 2420 const GURL& document_url) {
3159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3160 2422
3161 FilePath updated_file_path; 2423 FilePath updated_file_path;
3162 GDataFileError error = GDataToGDataFileError(status); 2424 GDataFileError error = util::GDataToGDataFileError(status);
3163 if (error == GDATA_FILE_OK) 2425 if (error == GDATA_FILE_OK)
3164 error = RenameFileOnFilesystem(file_path, new_name, &updated_file_path); 2426 error = RenameFileOnFilesystem(file_path, new_name, &updated_file_path);
3165 2427
3166 if (!callback.is_null()) 2428 if (!callback.is_null())
3167 callback.Run(error, updated_file_path); 2429 callback.Run(error, updated_file_path);
3168 } 2430 }
3169 2431
3170 void GDataFileSystem::OnCopyDocumentCompleted( 2432 void GDataFileSystem::OnCopyDocumentCompleted(
3171 const FilePath& dir_path, 2433 const FilePath& dir_path,
3172 const FileOperationCallback& callback, 2434 const FileOperationCallback& callback,
3173 GDataErrorCode status, 2435 GDataErrorCode status,
3174 scoped_ptr<base::Value> data) { 2436 scoped_ptr<base::Value> data) {
3175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3176 2438
3177 GDataFileError error = GDataToGDataFileError(status); 2439 GDataFileError error = util::GDataToGDataFileError(status);
3178 if (error != GDATA_FILE_OK) { 2440 if (error != GDATA_FILE_OK) {
3179 if (!callback.is_null()) 2441 if (!callback.is_null())
3180 callback.Run(error); 2442 callback.Run(error);
3181 2443
3182 return; 2444 return;
3183 } 2445 }
3184 2446
3185 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data)); 2447 scoped_ptr<DocumentEntry> doc_entry(DocumentEntry::ExtractAndParse(*data));
3186 if (!doc_entry.get()) { 2448 if (!doc_entry.get()) {
3187 if (!callback.is_null()) 2449 if (!callback.is_null())
(...skipping 19 matching lines...) Expand all
3207 } 2469 }
3208 2470
3209 void GDataFileSystem::OnAddEntryToDirectoryCompleted( 2471 void GDataFileSystem::OnAddEntryToDirectoryCompleted(
3210 const FileOperationCallback& callback, 2472 const FileOperationCallback& callback,
3211 const FilePath& file_path, 2473 const FilePath& file_path,
3212 const FilePath& dir_path, 2474 const FilePath& dir_path,
3213 GDataErrorCode status, 2475 GDataErrorCode status,
3214 const GURL& document_url) { 2476 const GURL& document_url) {
3215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3216 2478
3217 GDataFileError error = GDataToGDataFileError(status); 2479 GDataFileError error = util::GDataToGDataFileError(status);
3218 if (error == GDATA_FILE_OK) { 2480 if (error == GDATA_FILE_OK) {
3219 GDataEntry* entry = directory_service_->FindEntryByPathSync(file_path); 2481 GDataEntry* entry = directory_service_->FindEntryByPathSync(file_path);
3220 if (entry) { 2482 if (entry) {
3221 DCHECK_EQ(directory_service_->root(), entry->parent()); 2483 DCHECK_EQ(directory_service_->root(), entry->parent());
3222 error = AddEntryToDirectoryOnFilesystem(entry, dir_path); 2484 error = AddEntryToDirectoryOnFilesystem(entry, dir_path);
3223 } else { 2485 } else {
3224 error = GDATA_FILE_ERROR_NOT_FOUND; 2486 error = GDATA_FILE_ERROR_NOT_FOUND;
3225 } 2487 }
3226 } 2488 }
3227 2489
3228 if (!callback.is_null()) 2490 if (!callback.is_null())
3229 callback.Run(error); 2491 callback.Run(error);
3230 } 2492 }
3231 2493
3232 void GDataFileSystem::OnRemoveEntryFromDirectoryCompleted( 2494 void GDataFileSystem::OnRemoveEntryFromDirectoryCompleted(
3233 const FilePathUpdateCallback& callback, 2495 const FilePathUpdateCallback& callback,
3234 const FilePath& file_path, 2496 const FilePath& file_path,
3235 const FilePath& dir_path, 2497 const FilePath& dir_path,
3236 GDataErrorCode status, 2498 GDataErrorCode status,
3237 const GURL& document_url) { 2499 const GURL& document_url) {
3238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3239 2501
3240 FilePath updated_file_path = file_path; 2502 FilePath updated_file_path = file_path;
3241 GDataFileError error = GDataToGDataFileError(status); 2503 GDataFileError error = util::GDataToGDataFileError(status);
3242 if (error == GDATA_FILE_OK) 2504 if (error == GDATA_FILE_OK)
3243 error = RemoveEntryFromDirectoryOnFilesystem(file_path, dir_path, 2505 error = RemoveEntryFromDirectoryOnFilesystem(file_path, dir_path,
3244 &updated_file_path); 2506 &updated_file_path);
3245 2507
3246 if (!callback.is_null()) 2508 if (!callback.is_null())
3247 callback.Run(error, updated_file_path); 2509 callback.Run(error, updated_file_path);
3248 } 2510 }
3249 2511
3250 void GDataFileSystem::OnRemovedDocument( 2512 void GDataFileSystem::OnRemovedDocument(
3251 const FileOperationCallback& callback, 2513 const FileOperationCallback& callback,
3252 const FilePath& file_path, 2514 const FilePath& file_path,
3253 GDataErrorCode status, 2515 GDataErrorCode status,
3254 const GURL& document_url) { 2516 const GURL& document_url) {
3255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3256 2518
3257 GDataFileError error = GDataToGDataFileError(status); 2519 GDataFileError error = util::GDataToGDataFileError(status);
3258 2520
3259 if (error == GDATA_FILE_OK) 2521 if (error == GDATA_FILE_OK)
3260 error = RemoveEntryFromFileSystem(file_path); 2522 error = RemoveEntryFromFileSystem(file_path);
3261 2523
3262 if (!callback.is_null()) { 2524 if (!callback.is_null()) {
3263 callback.Run(error); 2525 callback.Run(error);
3264 } 2526 }
3265 } 2527 }
3266 2528
3267 void GDataFileSystem::OnFileDownloaded( 2529 void GDataFileSystem::OnFileDownloaded(
(...skipping 17 matching lines...) Expand all
3285 2547
3286 // At this point, the disk can be full or nearly full for several reasons: 2548 // At this point, the disk can be full or nearly full for several reasons:
3287 // - The expected file size was incorrect and the file was larger 2549 // - The expected file size was incorrect and the file was larger
3288 // - There was an in-flight download operation and it used up space 2550 // - There was an in-flight download operation and it used up space
3289 // - The disk became full for some user actions we cannot control 2551 // - The disk became full for some user actions we cannot control
3290 // (ex. the user might have downloaded a large file from a regular web site) 2552 // (ex. the user might have downloaded a large file from a regular web site)
3291 // 2553 //
3292 // If we don't have enough space, we return PLATFORM_FILE_ERROR_NO_SPACE, 2554 // If we don't have enough space, we return PLATFORM_FILE_ERROR_NO_SPACE,
3293 // and try to free up space, even if the file was downloaded successfully. 2555 // and try to free up space, even if the file was downloaded successfully.
3294 bool* has_enough_space = new bool(false); 2556 bool* has_enough_space = new bool(false);
3295 PostBlockingPoolSequencedTaskAndReply( 2557 util::PostBlockingPoolSequencedTaskAndReply(
3296 FROM_HERE, 2558 FROM_HERE,
3297 blocking_task_runner_, 2559 blocking_task_runner_,
3298 base::Bind(&GDataCache::FreeDiskSpaceIfNeededFor, 2560 base::Bind(&GDataCache::FreeDiskSpaceIfNeededFor,
3299 base::Unretained(cache_), 2561 base::Unretained(cache_),
3300 0, 2562 0,
3301 has_enough_space), 2563 has_enough_space),
3302 base::Bind(&GDataFileSystem::OnFileDownloadedAndSpaceChecked, 2564 base::Bind(&GDataFileSystem::OnFileDownloadedAndSpaceChecked,
3303 ui_weak_ptr_, 2565 ui_weak_ptr_,
3304 params, 2566 params,
3305 status, 2567 status,
(...skipping 15 matching lines...) Expand all
3321 } 2583 }
3322 2584
3323 void GDataFileSystem::OnFileDownloadedAndSpaceChecked( 2585 void GDataFileSystem::OnFileDownloadedAndSpaceChecked(
3324 const GetFileFromCacheParams& params, 2586 const GetFileFromCacheParams& params,
3325 GDataErrorCode status, 2587 GDataErrorCode status,
3326 const GURL& content_url, 2588 const GURL& content_url,
3327 const FilePath& downloaded_file_path, 2589 const FilePath& downloaded_file_path,
3328 bool* has_enough_space) { 2590 bool* has_enough_space) {
3329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3330 2592
3331 GDataFileError error = GDataToGDataFileError(status); 2593 GDataFileError error = util::GDataToGDataFileError(status);
3332 2594
3333 // Make sure that downloaded file is properly stored in cache. We don't have 2595 // Make sure that downloaded file is properly stored in cache. We don't have
3334 // to wait for this operation to finish since the user can already use the 2596 // to wait for this operation to finish since the user can already use the
3335 // downloaded file. 2597 // downloaded file.
3336 if (error == GDATA_FILE_OK) { 2598 if (error == GDATA_FILE_OK) {
3337 if (*has_enough_space) { 2599 if (*has_enough_space) {
3338 cache_->StoreOnUIThread( 2600 cache_->StoreOnUIThread(
3339 params.resource_id, 2601 params.resource_id,
3340 params.md5, 2602 params.md5,
3341 downloaded_file_path, 2603 downloaded_file_path,
3342 GDataCache::FILE_OPERATION_MOVE, 2604 GDataCache::FILE_OPERATION_MOVE,
3343 base::Bind(&GDataFileSystem::OnDownloadStoredToCache, 2605 base::Bind(&GDataFileSystem::OnDownloadStoredToCache,
3344 ui_weak_ptr_)); 2606 ui_weak_ptr_));
3345 } else { 2607 } else {
3346 // If we don't have enough space, remove the downloaded file, and 2608 // If we don't have enough space, remove the downloaded file, and
3347 // report "no space" error. 2609 // report "no space" error.
3348 PostBlockingPoolSequencedTask( 2610 util::PostBlockingPoolSequencedTask(
3349 FROM_HERE, 2611 FROM_HERE,
3350 blocking_task_runner_, 2612 blocking_task_runner_,
3351 base::Bind(base::IgnoreResult(&file_util::Delete), 2613 base::Bind(base::IgnoreResult(&file_util::Delete),
3352 downloaded_file_path, 2614 downloaded_file_path,
3353 false /* recursive*/)); 2615 false /* recursive*/));
3354 error = GDATA_FILE_ERROR_NO_SPACE; 2616 error = GDATA_FILE_ERROR_NO_SPACE;
3355 } 2617 }
3356 } 2618 }
3357 2619
3358 if (!params.get_file_callback.is_null()) { 2620 if (!params.get_file_callback.is_null()) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3459 if (error != GDATA_FILE_OK) 2721 if (error != GDATA_FILE_OK)
3460 return error; 2722 return error;
3461 2723
3462 // If resource_id is not empty, remove its corresponding file from cache. 2724 // If resource_id is not empty, remove its corresponding file from cache.
3463 if (!resource_id.empty()) 2725 if (!resource_id.empty())
3464 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback()); 2726 cache_->RemoveOnUIThread(resource_id, CacheOperationCallback());
3465 2727
3466 return GDATA_FILE_OK; 2728 return GDATA_FILE_OK;
3467 } 2729 }
3468 2730
3469 GDataFileError GDataWapiFeedLoader::UpdateFromFeed(
3470 const std::vector<DocumentFeed*>& feed_list,
3471 int start_changestamp,
3472 int root_feed_changestamp) {
3473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3474 DVLOG(1) << "Updating directory with a feed";
3475
3476 std::set<FilePath> changed_dirs;
3477
3478 GDataWapiFeedProcessor feed_processor(directory_service_);
3479 const GDataFileError error = feed_processor.ApplyFeeds(
3480 feed_list,
3481 start_changestamp,
3482 root_feed_changestamp,
3483 &changed_dirs);
3484
3485 // Don't send directory content change notification while performing
3486 // the initial content retrieval.
3487 const bool should_notify_directory_changed = (start_changestamp != 0);
3488 if (should_notify_directory_changed) {
3489 for (std::set<FilePath>::iterator dir_iter = changed_dirs.begin();
3490 dir_iter != changed_dirs.end(); ++dir_iter) {
3491 FOR_EACH_OBSERVER(Observer, observers_,
3492 OnDirectoryChanged(*dir_iter));
3493 }
3494 }
3495
3496 return error;
3497 }
3498
3499
3500 // static 2731 // static
3501 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id, 2732 void GDataFileSystem::RemoveStaleEntryOnUpload(const std::string& resource_id,
3502 GDataDirectory* parent_dir, 2733 GDataDirectory* parent_dir,
3503 GDataEntry* existing_entry) { 2734 GDataEntry* existing_entry) {
3504 if (existing_entry && 2735 if (existing_entry &&
3505 // This should always match, but just in case. 2736 // This should always match, but just in case.
3506 existing_entry->parent() == parent_dir) { 2737 existing_entry->parent() == parent_dir) {
3507 parent_dir->RemoveEntry(existing_entry); 2738 parent_dir->RemoveEntry(existing_entry);
3508 } else { 2739 } else {
3509 LOG(ERROR) << "Entry for the existing file not found: " << resource_id; 2740 LOG(ERROR) << "Entry for the existing file not found: " << resource_id;
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
3977 if (error != GDATA_FILE_OK) { 3208 if (error != GDATA_FILE_OK) {
3978 if (!callback.is_null()) 3209 if (!callback.is_null())
3979 callback.Run(error); 3210 callback.Run(error);
3980 return; 3211 return;
3981 } 3212 }
3982 3213
3983 // Step 3 of CloseFile: Retrieves the (possibly modified) PlatformFileInfo of 3214 // Step 3 of CloseFile: Retrieves the (possibly modified) PlatformFileInfo of
3984 // the cache file. 3215 // the cache file.
3985 base::PlatformFileInfo* file_info = new base::PlatformFileInfo; 3216 base::PlatformFileInfo* file_info = new base::PlatformFileInfo;
3986 bool* get_file_info_result = new bool(false); 3217 bool* get_file_info_result = new bool(false);
3987 PostBlockingPoolSequencedTaskAndReply( 3218 util::PostBlockingPoolSequencedTaskAndReply(
3988 FROM_HERE, 3219 FROM_HERE,
3989 blocking_task_runner_, 3220 blocking_task_runner_,
3990 base::Bind(&GetFileInfoOnBlockingPool, 3221 base::Bind(&GetFileInfoOnBlockingPool,
3991 local_cache_path, 3222 local_cache_path,
3992 base::Unretained(file_info), 3223 base::Unretained(file_info),
3993 base::Unretained(get_file_info_result)), 3224 base::Unretained(get_file_info_result)),
3994 base::Bind(&GDataFileSystem::OnGetModifiedFileInfoCompleteForCloseFile, 3225 base::Bind(&GDataFileSystem::OnGetModifiedFileInfoCompleteForCloseFile,
3995 ui_weak_ptr_, 3226 ui_weak_ptr_,
3996 file_path, 3227 file_path,
3997 base::Owned(file_info), 3228 base::Owned(file_info),
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
4158 // When no dirty cache is found, use the original entry info as is. 3389 // When no dirty cache is found, use the original entry info as is.
4159 if (error != GDATA_FILE_OK) { 3390 if (error != GDATA_FILE_OK) {
4160 if (!callback.is_null()) 3391 if (!callback.is_null())
4161 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); 3392 callback.Run(GDATA_FILE_OK, entry_proto.Pass());
4162 return; 3393 return;
4163 } 3394 }
4164 3395
4165 // If the cache is dirty, obtain the file info from the cache file itself. 3396 // If the cache is dirty, obtain the file info from the cache file itself.
4166 base::PlatformFileInfo* file_info = new base::PlatformFileInfo; 3397 base::PlatformFileInfo* file_info = new base::PlatformFileInfo;
4167 bool* get_file_info_result = new bool(false); 3398 bool* get_file_info_result = new bool(false);
4168 PostBlockingPoolSequencedTaskAndReply( 3399 util::PostBlockingPoolSequencedTaskAndReply(
4169 FROM_HERE, 3400 FROM_HERE,
4170 blocking_task_runner_, 3401 blocking_task_runner_,
4171 base::Bind(&GetFileInfoOnBlockingPool, 3402 base::Bind(&GetFileInfoOnBlockingPool,
4172 local_cache_path, 3403 local_cache_path,
4173 base::Unretained(file_info), 3404 base::Unretained(file_info),
4174 base::Unretained(get_file_info_result)), 3405 base::Unretained(get_file_info_result)),
4175 base::Bind(&GDataFileSystem::CheckLocalModificationAndRunAfterGetFileInfo, 3406 base::Bind(&GDataFileSystem::CheckLocalModificationAndRunAfterGetFileInfo,
4176 ui_weak_ptr_, 3407 ui_weak_ptr_,
4177 base::Passed(&entry_proto), 3408 base::Passed(&entry_proto),
4178 callback, 3409 callback,
(...skipping 15 matching lines...) Expand all
4194 } 3425 }
4195 3426
4196 PlatformFileInfoProto entry_file_info; 3427 PlatformFileInfoProto entry_file_info;
4197 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info); 3428 GDataEntry::ConvertPlatformFileInfoToProto(*file_info, &entry_file_info);
4198 *entry_proto->mutable_file_info() = entry_file_info; 3429 *entry_proto->mutable_file_info() = entry_file_info;
4199 if (!callback.is_null()) 3430 if (!callback.is_null())
4200 callback.Run(GDATA_FILE_OK, entry_proto.Pass()); 3431 callback.Run(GDATA_FILE_OK, entry_proto.Pass());
4201 } 3432 }
4202 3433
4203 } // namespace gdata 3434 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system.h ('k') | chrome/browser/chromeos/gdata/gdata_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698