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

Side by Side Diff: chrome/browser/chromeos/drive/file_system/remove_operation.cc

Issue 68543002: drive: Support offline delete (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move to drive/other and mark as deleted Created 7 years, 1 month 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/drive/file_system/remove_operation.h" 5 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
6 6
7 #include "base/sequenced_task_runner.h" 7 #include "base/sequenced_task_runner.h"
8 #include "chrome/browser/chromeos/drive/drive.pb.h" 8 #include "chrome/browser/chromeos/drive/drive.pb.h"
9 #include "chrome/browser/chromeos/drive/file_cache.h" 9 #include "chrome/browser/chromeos/drive/file_cache.h"
10 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" 10 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h" 11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/chromeos/drive/job_scheduler.h" 12 #include "chrome/browser/chromeos/drive/resource_metadata.h"
13 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 14
15 using content::BrowserThread; 15 using content::BrowserThread;
16 16
17 namespace drive { 17 namespace drive {
18 namespace file_system { 18 namespace file_system {
19 19
20 namespace { 20 namespace {
21 21
22 // Checks local metadata state before requesting remote delete. 22 // Recursively mark entries as deleted.
23 // |parent_resource_id| is set to the resource ID of the parent directory of 23 FileError SetDeletedRecursively(internal::ResourceMetadata* metadata,
24 // |path|. If it is a special folder like drive/other, empty string is set. 24 const ResourceEntry& entry) {
25 // |entry| is the resource entry for the |path|. 25 ResourceEntry new_entry(entry);
26 FileError CheckLocalState(internal::ResourceMetadata* metadata, 26 new_entry.set_deleted(true);
27 const base::FilePath& path, 27 FileError error = metadata->RefreshEntry(new_entry);
28 bool is_recursive,
29 std::string* parent_resource_id,
30 ResourceEntry* entry) {
31 std::string local_id;
32 FileError error = metadata->GetIdByPath(path, &local_id);
33 if (error != FILE_ERROR_OK) 28 if (error != FILE_ERROR_OK)
34 return error; 29 return error;
35 30
36 error = metadata->GetResourceEntryById(local_id, entry); 31 if (entry.file_info().is_directory()) {
32 ResourceEntryVector entries;
33 error = metadata->ReadDirectoryById(entry.local_id(), &entries);
34 if (error != FILE_ERROR_OK)
35 return error;
36
37 for (size_t i = 0; i < entries.size(); ++i) {
38 error = SetDeletedRecursively(metadata, entries[i]);
39 if (error != FILE_ERROR_OK)
40 return error;
41 }
42 }
43 return FILE_ERROR_OK;
44 }
45
46 // Removes cache file and moves the metadata entry to "other" directory and mark
47 // the entry as deleted.
48 FileError UpdateLocalState(internal::ResourceMetadata* metadata,
49 internal::FileCache* cache,
50 const base::FilePath& path,
51 bool is_recursive,
52 std::string* local_id,
53 base::FilePath* changed_directory_path) {
54 FileError error = metadata->GetIdByPath(path, local_id);
37 if (error != FILE_ERROR_OK) 55 if (error != FILE_ERROR_OK)
38 return error; 56 return error;
39 57
40 if (entry->file_info().is_directory() && !is_recursive) { 58 ResourceEntry entry;
59 error = metadata->GetResourceEntryById(*local_id, &entry);
60 if (error != FILE_ERROR_OK)
61 return error;
62
63 if (entry.file_info().is_directory() && !is_recursive) {
41 // Check emptiness of the directory. 64 // Check emptiness of the directory.
42 ResourceEntryVector entries; 65 ResourceEntryVector entries;
43 error = metadata->ReadDirectoryByPath(path, &entries); 66 error = metadata->ReadDirectoryById(*local_id, &entries);
44 if (error != FILE_ERROR_OK) 67 if (error != FILE_ERROR_OK)
45 return error; 68 return error;
46 if (!entries.empty()) 69 if (!entries.empty())
47 return FILE_ERROR_NOT_EMPTY; 70 return FILE_ERROR_NOT_EMPTY;
48 } 71 }
49 72
50 // Get the resource_id of the parent folder. If it is a special folder that 73 *changed_directory_path = metadata->GetFilePath(*local_id).DirName();
51 // does not have the server side ID, returns an empty string (not an error).
52 if (util::IsSpecialResourceId(entry->parent_local_id())) {
53 *parent_resource_id = "";
54 } else {
55 ResourceEntry parent_entry;
56 error = metadata->GetResourceEntryById(entry->parent_local_id(),
57 &parent_entry);
58 if (error != FILE_ERROR_OK)
59 return error;
60 *parent_resource_id = parent_entry.resource_id();
61 }
62 74
63 return FILE_ERROR_OK; 75 // Move to "other" directory.
64 } 76 entry.set_parent_local_id(util::kDriveOtherDirLocalId);
65 77 error = metadata->RefreshEntry(entry);
66 // Updates local metadata and cache state after remote delete.
67 FileError UpdateLocalStateAfterDelete(internal::ResourceMetadata* metadata,
68 internal::FileCache* cache,
69 const std::string& local_id,
70 base::FilePath* changed_directory_path) {
71 *changed_directory_path = metadata->GetFilePath(local_id).DirName();
72 FileError error = metadata->RemoveEntry(local_id);
73 if (error != FILE_ERROR_OK) 78 if (error != FILE_ERROR_OK)
74 return error; 79 return error;
75 80
76 error = cache->Remove(local_id); 81 // Mark as deleted recursively.
77 DLOG_IF(ERROR, error != FILE_ERROR_OK) << "Failed to remove: " << local_id; 82 error = SetDeletedRecursively(metadata, entry);
78
79 return FILE_ERROR_OK;
80 }
81
82 // Updates local metadata and after remote unparenting.
83 FileError UpdateLocalStateAfterUnparent(
84 internal::ResourceMetadata* metadata,
85 const std::string& local_id,
86 base::FilePath* changed_directory_path) {
87 *changed_directory_path = metadata->GetFilePath(local_id).DirName();
88
89 ResourceEntry entry;
90 FileError error = metadata->GetResourceEntryById(local_id, &entry);
91 if (error != FILE_ERROR_OK) 83 if (error != FILE_ERROR_OK)
92 return error; 84 return error;
93 entry.set_parent_local_id(util::kDriveOtherDirLocalId); 85
94 return metadata->RefreshEntry(entry); 86 return cache->Remove(*local_id);
95 } 87 }
96 88
97 } // namespace 89 } // namespace
98 90
99 RemoveOperation::RemoveOperation( 91 RemoveOperation::RemoveOperation(
100 base::SequencedTaskRunner* blocking_task_runner, 92 base::SequencedTaskRunner* blocking_task_runner,
101 OperationObserver* observer, 93 OperationObserver* observer,
102 JobScheduler* scheduler,
103 internal::ResourceMetadata* metadata, 94 internal::ResourceMetadata* metadata,
104 internal::FileCache* cache) 95 internal::FileCache* cache)
105 : blocking_task_runner_(blocking_task_runner), 96 : blocking_task_runner_(blocking_task_runner),
106 observer_(observer), 97 observer_(observer),
107 scheduler_(scheduler),
108 metadata_(metadata), 98 metadata_(metadata),
109 cache_(cache), 99 cache_(cache),
110 weak_ptr_factory_(this) { 100 weak_ptr_factory_(this) {
111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 } 102 }
113 103
114 RemoveOperation::~RemoveOperation() { 104 RemoveOperation::~RemoveOperation() {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116 } 106 }
117 107
118 void RemoveOperation::Remove(const base::FilePath& path, 108 void RemoveOperation::Remove(const base::FilePath& path,
119 bool is_recursive, 109 bool is_recursive,
120 const FileOperationCallback& callback) { 110 const FileOperationCallback& callback) {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122 DCHECK(!callback.is_null()); 112 DCHECK(!callback.is_null());
123 113
124 std::string* parent_resource_id = new std::string; 114 std::string* local_id = new std::string;
125 ResourceEntry* entry = new ResourceEntry;
126 base::PostTaskAndReplyWithResult(
127 blocking_task_runner_.get(),
128 FROM_HERE,
129 base::Bind(&CheckLocalState,
130 metadata_,
131 path,
132 is_recursive,
133 parent_resource_id,
134 entry),
135 base::Bind(&RemoveOperation::RemoveAfterCheckLocalState,
136 weak_ptr_factory_.GetWeakPtr(),
137 callback,
138 base::Owned(parent_resource_id),
139 base::Owned(entry)));
140 }
141
142 void RemoveOperation::RemoveAfterCheckLocalState(
143 const FileOperationCallback& callback,
144 const std::string* parent_resource_id,
145 const ResourceEntry* entry,
146 FileError error) {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
148 DCHECK(!callback.is_null());
149
150 if (error != FILE_ERROR_OK) {
151 callback.Run(error);
152 return;
153 }
154
155 // To match with the behavior of drive.google.com:
156 // Removal of shared entries under MyDrive is just removing from the parent.
157 // The entry will stay in shared-with-me (in other words, in "drive/other".)
158 //
159 // TODO(kinaba): to be more precise, we might be better to branch by whether
160 // or not the current account is an owner of the file. The code below is
161 // written under the assumption that |shared_with_me| coincides with that.
162 if (entry->shared_with_me() && !parent_resource_id->empty()) {
163 scheduler_->RemoveResourceFromDirectory(
164 *parent_resource_id,
165 entry->resource_id(),
166 ClientContext(USER_INITIATED),
167 base::Bind(&RemoveOperation::RemoveAfterUpdateRemoteState,
168 weak_ptr_factory_.GetWeakPtr(),
169 callback,
170 base::Bind(&UpdateLocalStateAfterUnparent,
171 metadata_,
172 entry->local_id())));
173 } else {
174 // Otherwise try sending the entry to trash.
175 scheduler_->DeleteResource(
176 entry->resource_id(),
177 ClientContext(USER_INITIATED),
178 base::Bind(&RemoveOperation::RemoveAfterUpdateRemoteState,
179 weak_ptr_factory_.GetWeakPtr(),
180 callback,
181 base::Bind(&UpdateLocalStateAfterDelete,
182 metadata_,
183 cache_,
184 entry->local_id())));
185 }
186 }
187
188 void RemoveOperation::RemoveAfterUpdateRemoteState(
189 const FileOperationCallback& callback,
190 const base::Callback<FileError(base::FilePath*)>& local_update_task,
191 google_apis::GDataErrorCode status) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 DCHECK(!callback.is_null());
194
195 FileError error = GDataToFileError(status);
196 if (error != FILE_ERROR_OK) {
197 callback.Run(error);
198 return;
199 }
200
201 base::FilePath* changed_directory_path = new base::FilePath; 115 base::FilePath* changed_directory_path = new base::FilePath;
202 base::PostTaskAndReplyWithResult( 116 base::PostTaskAndReplyWithResult(
203 blocking_task_runner_.get(), 117 blocking_task_runner_.get(),
204 FROM_HERE, 118 FROM_HERE,
205 base::Bind(local_update_task, changed_directory_path), 119 base::Bind(&UpdateLocalState,
120 metadata_,
121 cache_,
122 path,
123 is_recursive,
124 local_id,
125 changed_directory_path),
206 base::Bind(&RemoveOperation::RemoveAfterUpdateLocalState, 126 base::Bind(&RemoveOperation::RemoveAfterUpdateLocalState,
207 weak_ptr_factory_.GetWeakPtr(), 127 weak_ptr_factory_.GetWeakPtr(),
208 callback, 128 callback,
129 base::Owned(local_id),
209 base::Owned(changed_directory_path))); 130 base::Owned(changed_directory_path)));
210 } 131 }
211 132
212 void RemoveOperation::RemoveAfterUpdateLocalState( 133 void RemoveOperation::RemoveAfterUpdateLocalState(
213 const FileOperationCallback& callback, 134 const FileOperationCallback& callback,
135 const std::string* local_id,
214 const base::FilePath* changed_directory_path, 136 const base::FilePath* changed_directory_path,
215 FileError error) { 137 FileError error) {
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
217 DCHECK(!callback.is_null()); 139 DCHECK(!callback.is_null());
218 140
219 if (error == FILE_ERROR_OK) 141 if (error == FILE_ERROR_OK) {
220 observer_->OnDirectoryChangedByOperation(*changed_directory_path); 142 observer_->OnDirectoryChangedByOperation(*changed_directory_path);
143 observer_->OnEntryRemovedByOperation(*local_id);
144 }
221 145
222 callback.Run(error); 146 callback.Run(error);
223 } 147 }
224 148
225 } // namespace file_system 149 } // namespace file_system
226 } // namespace drive 150 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698