853039ee9de9f44149d366fe1219b34efcc4893b
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / sync / entry_revert_performer.cc
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.
4
5 #include "chrome/browser/chromeos/drive/sync/entry_revert_performer.h"
6
7 #include "chrome/browser/chromeos/drive/change_list_processor.h"
8 #include "chrome/browser/chromeos/drive/drive.pb.h"
9 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
10 #include "chrome/browser/chromeos/drive/job_scheduler.h"
11 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
12 #include "chrome/browser/chromeos/drive/resource_metadata.h"
13 #include "content/public/browser/browser_thread.h"
14
15 using content::BrowserThread;
16
17 namespace drive {
18 namespace internal {
19 namespace {
20
21 FileError FinishRevert(ResourceMetadata* metadata,
22                        const std::string& local_id,
23                        google_apis::GDataErrorCode status,
24                        scoped_ptr<google_apis::ResourceEntry> resource_entry,
25                        std::set<base::FilePath>* changed_directories) {
26   ResourceEntry entry;
27   std::string parent_resource_id;
28   FileError error = GDataToFileError(status);
29   switch (error) {
30     case FILE_ERROR_OK:
31       if (!ConvertToResourceEntry(*resource_entry, &entry, &parent_resource_id))
32         return FILE_ERROR_NOT_A_FILE;
33       break;
34
35     case FILE_ERROR_NOT_FOUND:
36       entry.set_deleted(true);
37       break;
38
39     default:
40       return error;
41   }
42
43   const base::FilePath original_path = metadata->GetFilePath(local_id);
44
45   if (entry.deleted()) {
46     error = metadata->RemoveEntry(local_id);
47     if (error != FILE_ERROR_OK)
48       return error;
49
50     changed_directories->insert(original_path.DirName());
51   } else {
52     error = ChangeListProcessor::SetParentLocalIdOfEntry(metadata, &entry,
53                                                          parent_resource_id);
54     if (error != FILE_ERROR_OK)
55       return error;
56
57     entry.set_local_id(local_id);
58     error = metadata->RefreshEntry(entry);
59     if (error != FILE_ERROR_OK)
60       return error;
61
62     changed_directories->insert(metadata->GetFilePath(entry.parent_local_id()));
63     changed_directories->insert(original_path.DirName());
64   }
65   return FILE_ERROR_OK;
66 }
67
68 }  // namespace
69
70 EntryRevertPerformer::EntryRevertPerformer(
71     base::SequencedTaskRunner* blocking_task_runner,
72     file_system::OperationObserver* observer,
73     JobScheduler* scheduler,
74     ResourceMetadata* metadata)
75     : blocking_task_runner_(blocking_task_runner),
76       observer_(observer),
77       scheduler_(scheduler),
78       metadata_(metadata),
79       weak_ptr_factory_(this) {
80   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81 }
82
83 EntryRevertPerformer::~EntryRevertPerformer() {
84   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85 }
86
87 void EntryRevertPerformer::RevertEntry(const std::string& local_id,
88                                        const ClientContext& context,
89                                        const FileOperationCallback& callback) {
90   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
91   DCHECK(!callback.is_null());
92
93   scoped_ptr<ResourceEntry> entry(new ResourceEntry);
94   ResourceEntry* entry_ptr = entry.get();
95   base::PostTaskAndReplyWithResult(
96       blocking_task_runner_.get(),
97       FROM_HERE,
98       base::Bind(&ResourceMetadata::GetResourceEntryById,
99                  base::Unretained(metadata_), local_id, entry_ptr),
100       base::Bind(&EntryRevertPerformer::RevertEntryAfterPrepare,
101                  weak_ptr_factory_.GetWeakPtr(), context, callback,
102                  base::Passed(&entry)));
103 }
104
105 void EntryRevertPerformer::RevertEntryAfterPrepare(
106     const ClientContext& context,
107     const FileOperationCallback& callback,
108     scoped_ptr<ResourceEntry> entry,
109     FileError error) {
110   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111   DCHECK(!callback.is_null());
112
113   if (error == FILE_ERROR_OK && entry->resource_id().empty())
114     error = FILE_ERROR_INVALID_OPERATION;
115
116   if (error != FILE_ERROR_OK) {
117     callback.Run(error);
118     return;
119   }
120
121   scheduler_->GetResourceEntry(
122       entry->resource_id(),
123       context,
124       base::Bind(&EntryRevertPerformer::RevertEntryAfterGetResourceEntry,
125                  weak_ptr_factory_.GetWeakPtr(), callback, entry->local_id()));
126 }
127
128 void EntryRevertPerformer::RevertEntryAfterGetResourceEntry(
129     const FileOperationCallback& callback,
130     const std::string& local_id,
131     google_apis::GDataErrorCode status,
132     scoped_ptr<google_apis::ResourceEntry> resource_entry) {
133   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
134   DCHECK(!callback.is_null());
135
136   std::set<base::FilePath>* changed_directories = new std::set<base::FilePath>;
137   base::PostTaskAndReplyWithResult(
138       blocking_task_runner_.get(),
139       FROM_HERE,
140       base::Bind(&FinishRevert, metadata_, local_id, status,
141                  base::Passed(&resource_entry), changed_directories),
142       base::Bind(&EntryRevertPerformer::RevertEntryAfterFinishRevert,
143                  weak_ptr_factory_.GetWeakPtr(), callback,
144                  base::Owned(changed_directories)));
145 }
146
147 void EntryRevertPerformer::RevertEntryAfterFinishRevert(
148     const FileOperationCallback& callback,
149     const std::set<base::FilePath>* changed_directories,
150     FileError error) {
151   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152   DCHECK(!callback.is_null());
153
154   for (std::set<base::FilePath>::const_iterator it =
155            changed_directories->begin(); it != changed_directories->end(); ++it)
156     observer_->OnDirectoryChangedByOperation(*it);
157
158   callback.Run(error);
159 }
160
161 }  // namespace internal
162 }  // namespace drive