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
;
21 // Looks up ResourceEntry for source entry and its parent.
22 FileError
PrepareUpdate(ResourceMetadata
* metadata
,
23 const std::string
& local_id
,
25 ResourceEntry
* parent_entry
) {
26 FileError error
= metadata
->GetResourceEntryById(local_id
, entry
);
27 if (error
!= FILE_ERROR_OK
)
30 error
= metadata
->GetResourceEntryById(entry
->parent_local_id(),
32 if (error
!= FILE_ERROR_OK
)
35 switch (entry
->metadata_edit_state()) {
36 case ResourceEntry::CLEAN
: // Nothing to do.
37 case ResourceEntry::SYNCING
: // Error during the last update. Go ahead.
40 case ResourceEntry::DIRTY
:
41 entry
->set_metadata_edit_state(ResourceEntry::SYNCING
);
42 error
= metadata
->RefreshEntry(*entry
);
43 if (error
!= FILE_ERROR_OK
)
50 FileError
FinishUpdate(ResourceMetadata
* metadata
,
51 const std::string
& local_id
) {
53 FileError error
= metadata
->GetResourceEntryById(local_id
, &entry
);
54 if (error
!= FILE_ERROR_OK
)
57 switch (entry
.metadata_edit_state()) {
58 case ResourceEntry::CLEAN
: // Nothing to do.
59 case ResourceEntry::DIRTY
: // Entry was edited again during the update.
62 case ResourceEntry::SYNCING
:
63 entry
.set_metadata_edit_state(ResourceEntry::CLEAN
);
64 error
= metadata
->RefreshEntry(entry
);
65 if (error
!= FILE_ERROR_OK
)
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
),
82 remove_performer_(new RemovePerformer(blocking_task_runner
,
86 entry_revert_performer_(new EntryRevertPerformer(blocking_task_runner
,
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(),
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
,
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
124 DCHECK(!callback
.is_null());
126 if (error
!= FILE_ERROR_OK
) {
131 // Trashed entry should be removed.
132 if (entry
->parent_local_id() == util::kDriveTrashDirLocalId
) {
133 remove_performer_
->Remove(entry
->local_id(), callback
);
137 if (entry
->metadata_edit_state() == ResourceEntry::CLEAN
) {
138 callback
.Run(FILE_ERROR_OK
);
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
);
167 FileError error
= GDataToFileError(status
);
168 if (error
!= FILE_ERROR_OK
) {
173 base::PostTaskAndReplyWithResult(
174 blocking_task_runner_
.get(),
176 base::Bind(&FinishUpdate
, metadata_
, local_id
),
180 } // namespace internal