Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / sync / entry_update_performer.cc
blobe60cc03674b0c21d218f3447c95eeb9835661bb3
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/drive/sync/entry_update_performer.h"
7 #include "chrome/browser/chromeos/drive/drive.pb.h"
8 #include "chrome/browser/chromeos/drive/file_system_util.h"
9 #include "chrome/browser/chromeos/drive/job_scheduler.h"
10 #include "chrome/browser/chromeos/drive/resource_metadata.h"
11 #include "chrome/browser/chromeos/drive/sync/entry_revert_performer.h"
12 #include "chrome/browser/chromeos/drive/sync/remove_performer.h"
13 #include "content/public/browser/browser_thread.h"
15 using content::BrowserThread;
17 namespace drive {
18 namespace internal {
19 namespace {
21 // Looks up ResourceEntry for source entry and its parent.
22 FileError PrepareUpdate(ResourceMetadata* metadata,
23 const std::string& local_id,
24 ResourceEntry* entry,
25 ResourceEntry* parent_entry) {
26 FileError error = metadata->GetResourceEntryById(local_id, entry);
27 if (error != FILE_ERROR_OK)
28 return error;
30 error = metadata->GetResourceEntryById(entry->parent_local_id(),
31 parent_entry);
32 if (error != FILE_ERROR_OK)
33 return error;
35 switch (entry->metadata_edit_state()) {
36 case ResourceEntry::CLEAN: // Nothing to do.
37 case ResourceEntry::SYNCING: // Error during the last update. Go ahead.
38 break;
40 case ResourceEntry::DIRTY:
41 entry->set_metadata_edit_state(ResourceEntry::SYNCING);
42 error = metadata->RefreshEntry(*entry);
43 if (error != FILE_ERROR_OK)
44 return error;
45 break;
47 return FILE_ERROR_OK;
50 FileError FinishUpdate(ResourceMetadata* metadata,
51 const std::string& local_id) {
52 ResourceEntry entry;
53 FileError error = metadata->GetResourceEntryById(local_id, &entry);
54 if (error != FILE_ERROR_OK)
55 return error;
57 switch (entry.metadata_edit_state()) {
58 case ResourceEntry::CLEAN: // Nothing to do.
59 case ResourceEntry::DIRTY: // Entry was edited again during the update.
60 break;
62 case ResourceEntry::SYNCING:
63 entry.set_metadata_edit_state(ResourceEntry::CLEAN);
64 error = metadata->RefreshEntry(entry);
65 if (error != FILE_ERROR_OK)
66 return error;
67 break;
69 return FILE_ERROR_OK;
72 } // namespace
74 EntryUpdatePerformer::EntryUpdatePerformer(
75 base::SequencedTaskRunner* blocking_task_runner,
76 file_system::OperationObserver* observer,
77 JobScheduler* scheduler,
78 ResourceMetadata* metadata)
79 : blocking_task_runner_(blocking_task_runner),
80 scheduler_(scheduler),
81 metadata_(metadata),
82 remove_performer_(new RemovePerformer(blocking_task_runner,
83 observer,
84 scheduler,
85 metadata)),
86 entry_revert_performer_(new EntryRevertPerformer(blocking_task_runner,
87 observer,
88 scheduler,
89 metadata)),
90 weak_ptr_factory_(this) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
94 EntryUpdatePerformer::~EntryUpdatePerformer() {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 void EntryUpdatePerformer::UpdateEntry(const std::string& local_id,
99 const FileOperationCallback& callback) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101 DCHECK(!callback.is_null());
103 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
104 scoped_ptr<ResourceEntry> parent_entry(new ResourceEntry);
105 ResourceEntry* entry_ptr = entry.get();
106 ResourceEntry* parent_entry_ptr = parent_entry.get();
107 base::PostTaskAndReplyWithResult(
108 blocking_task_runner_.get(),
109 FROM_HERE,
110 base::Bind(&PrepareUpdate,
111 metadata_, local_id, entry_ptr, parent_entry_ptr),
112 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterPrepare,
113 weak_ptr_factory_.GetWeakPtr(), callback,
114 base::Passed(&entry),
115 base::Passed(&parent_entry)));
118 void EntryUpdatePerformer::UpdateEntryAfterPrepare(
119 const FileOperationCallback& callback,
120 scoped_ptr<ResourceEntry> entry,
121 scoped_ptr<ResourceEntry> parent_entry,
122 FileError error) {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 DCHECK(!callback.is_null());
126 if (error != FILE_ERROR_OK) {
127 callback.Run(error);
128 return;
131 // Trashed entry should be removed.
132 if (entry->parent_local_id() == util::kDriveTrashDirLocalId) {
133 remove_performer_->Remove(entry->local_id(), callback);
134 return;
137 if (entry->metadata_edit_state() == ResourceEntry::CLEAN) {
138 callback.Run(FILE_ERROR_OK);
139 return;
142 base::Time last_modified =
143 base::Time::FromInternalValue(entry->file_info().last_modified());
144 base::Time last_accessed =
145 base::Time::FromInternalValue(entry->file_info().last_accessed());
146 scheduler_->UpdateResource(
147 entry->resource_id(), parent_entry->resource_id(),
148 entry->title(), last_modified, last_accessed,
149 ClientContext(BACKGROUND),
150 base::Bind(&EntryUpdatePerformer::UpdateEntryAfterUpdateResource,
151 weak_ptr_factory_.GetWeakPtr(), callback, entry->local_id()));
154 void EntryUpdatePerformer::UpdateEntryAfterUpdateResource(
155 const FileOperationCallback& callback,
156 const std::string& local_id,
157 google_apis::GDataErrorCode status,
158 scoped_ptr<google_apis::ResourceEntry> resource_entry) {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 if (status == google_apis::HTTP_FORBIDDEN) {
162 // Editing this entry is not allowed, revert local changes.
163 entry_revert_performer_->RevertEntry(local_id, callback);
164 return;
167 FileError error = GDataToFileError(status);
168 if (error != FILE_ERROR_OK) {
169 callback.Run(error);
170 return;
173 base::PostTaskAndReplyWithResult(
174 blocking_task_runner_.get(),
175 FROM_HERE,
176 base::Bind(&FinishUpdate, metadata_, local_id),
177 callback);
180 } // namespace internal
181 } // namespace drive