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

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

Issue 98513003: drive: Support offline move/rename (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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/move_operation.h" 5 #include "chrome/browser/chromeos/drive/file_system/move_operation.h"
6 6
7 #include "base/sequenced_task_runner.h"
7 #include "chrome/browser/chromeos/drive/drive.pb.h" 8 #include "chrome/browser/chromeos/drive/drive.pb.h"
8 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" 9 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
9 #include "chrome/browser/chromeos/drive/job_scheduler.h"
10 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
11 #include "chrome/browser/chromeos/drive/resource_metadata.h" 10 #include "chrome/browser/chromeos/drive/resource_metadata.h"
12 #include "content/public/browser/browser_thread.h" 11 #include "content/public/browser/browser_thread.h"
13 12
14 using content::BrowserThread; 13 using content::BrowserThread;
15 14
16 namespace drive { 15 namespace drive {
17 namespace file_system { 16 namespace file_system {
18 namespace { 17 namespace {
19 18
20 // Looks up ResourceEntry for source entry and the destination directory. 19 // Looks up ResourceEntry for source entry and the destination directory.
21 FileError PrepareMove(internal::ResourceMetadata* metadata, 20 FileError UpdateLocalState(internal::ResourceMetadata* metadata,
22 const base::FilePath& src_path, 21 const base::FilePath& src_path,
23 const base::FilePath& dest_parent_path, 22 const base::FilePath& dest_path,
24 ResourceEntry* src_entry, 23 bool preserve_last_modified,
25 ResourceEntry* src_parent_entry, 24 std::string* local_id) {
26 ResourceEntry* dest_parent_entry) { 25 ResourceEntry entry;
27 FileError error = metadata->GetResourceEntryByPath(src_path, src_entry); 26 FileError error = metadata->GetResourceEntryByPath(src_path, &entry);
27 if (error != FILE_ERROR_OK)
28 return error;
29 *local_id = entry.local_id();
30
31 ResourceEntry parent_entry;
32 error = metadata->GetResourceEntryByPath(dest_path.DirName(), &parent_entry);
28 if (error != FILE_ERROR_OK) 33 if (error != FILE_ERROR_OK)
29 return error; 34 return error;
30 35
31 error = metadata->GetResourceEntryById(src_entry->parent_local_id(), 36 // The parent must be a directory.
32 src_parent_entry); 37 if (!parent_entry.file_info().is_directory())
33 if (error != FILE_ERROR_OK) 38 return FILE_ERROR_NOT_A_DIRECTORY;
34 return error;
35 39
36 return metadata->GetResourceEntryByPath(dest_parent_path, dest_parent_entry); 40 // Strip the extension for a hosted document if necessary.
37 } 41 const std::string new_extension =
42 base::FilePath(dest_path.Extension()).AsUTF8Unsafe();
43 const bool has_hosted_document_extension =
44 entry.has_file_specific_info() &&
45 entry.file_specific_info().is_hosted_document() &&
46 new_extension == entry.file_specific_info().document_extension();
47 const std::string new_title =
48 has_hosted_document_extension ?
49 dest_path.BaseName().RemoveExtension().AsUTF8Unsafe() :
50 dest_path.BaseName().AsUTF8Unsafe();
38 51
39 // Refreshes the corresponding entry in the metadata with the given one. 52 // Update last_modified.
40 FileError RefreshEntry(internal::ResourceMetadata* metadata, 53 if (!preserve_last_modified) {
41 scoped_ptr<google_apis::ResourceEntry> resource_entry) { 54 entry.mutable_file_info()->set_last_modified(
42 ResourceEntry entry; 55 base::Time::Now().ToInternalValue());
43 std::string parent_resource_id; 56 }
44 if (!ConvertToResourceEntry(*resource_entry, &entry, &parent_resource_id))
45 return FILE_ERROR_FAILED;
46 57
47 std::string parent_local_id; 58 entry.set_title(new_title);
48 FileError error = metadata->GetIdByResourceId(parent_resource_id, 59 entry.set_parent_local_id(parent_entry.local_id());
49 &parent_local_id); 60 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
50 if (error != FILE_ERROR_OK)
51 return error;
52 entry.set_parent_local_id(parent_local_id);
53
54 std::string local_id;
55 error = metadata->GetIdByResourceId(entry.resource_id(), &local_id);
56 if (error != FILE_ERROR_OK)
57 return error;
58 entry.set_local_id(local_id);
59
60 return metadata->RefreshEntry(entry); 61 return metadata->RefreshEntry(entry);
61 } 62 }
62 63
63 } // namespace 64 } // namespace
64 65
65 struct MoveOperation::MoveParams {
66 base::FilePath src_file_path;
67 base::FilePath dest_file_path;
68 bool preserve_last_modified;
69 FileOperationCallback callback;
70 };
71
72 MoveOperation::MoveOperation(base::SequencedTaskRunner* blocking_task_runner, 66 MoveOperation::MoveOperation(base::SequencedTaskRunner* blocking_task_runner,
73 OperationObserver* observer, 67 OperationObserver* observer,
74 JobScheduler* scheduler,
75 internal::ResourceMetadata* metadata) 68 internal::ResourceMetadata* metadata)
76 : blocking_task_runner_(blocking_task_runner), 69 : blocking_task_runner_(blocking_task_runner),
77 observer_(observer), 70 observer_(observer),
78 scheduler_(scheduler),
79 metadata_(metadata), 71 metadata_(metadata),
80 weak_ptr_factory_(this) { 72 weak_ptr_factory_(this) {
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
82 } 74 }
83 75
84 MoveOperation::~MoveOperation() { 76 MoveOperation::~MoveOperation() {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
86 } 78 }
87 79
88 void MoveOperation::Move(const base::FilePath& src_file_path, 80 void MoveOperation::Move(const base::FilePath& src_file_path,
89 const base::FilePath& dest_file_path, 81 const base::FilePath& dest_file_path,
90 bool preserve_last_modified, 82 bool preserve_last_modified,
91 const FileOperationCallback& callback) { 83 const FileOperationCallback& callback) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93 DCHECK(!callback.is_null()); 85 DCHECK(!callback.is_null());
94 86
95 MoveParams params; 87 std::string* local_id = new std::string;
96 params.src_file_path = src_file_path;
97 params.dest_file_path = dest_file_path;
98 params.preserve_last_modified = preserve_last_modified;
99 params.callback = callback;
100
101 scoped_ptr<ResourceEntry> src_entry(new ResourceEntry);
102 scoped_ptr<ResourceEntry> src_parent_entry(new ResourceEntry);
103 scoped_ptr<ResourceEntry> dest_parent_entry(new ResourceEntry);
104 ResourceEntry* src_entry_ptr = src_entry.get();
105 ResourceEntry* src_parent_entry_ptr = src_parent_entry.get();
106 ResourceEntry* dest_parent_entry_ptr = dest_parent_entry.get();
107 base::PostTaskAndReplyWithResult( 88 base::PostTaskAndReplyWithResult(
108 blocking_task_runner_.get(), 89 blocking_task_runner_.get(),
109 FROM_HERE, 90 FROM_HERE,
110 base::Bind(&PrepareMove, 91 base::Bind(&UpdateLocalState,
111 metadata_, src_file_path, dest_file_path.DirName(), 92 metadata_,
112 src_entry_ptr, src_parent_entry_ptr, dest_parent_entry_ptr), 93 src_file_path,
113 base::Bind(&MoveOperation::MoveAfterPrepare, 94 dest_file_path,
114 weak_ptr_factory_.GetWeakPtr(), params, 95 preserve_last_modified,
115 base::Passed(&src_entry), 96 local_id),
116 base::Passed(&src_parent_entry), 97 base::Bind(&MoveOperation::MoveAfterUpdateLocalState,
117 base::Passed(&dest_parent_entry))); 98 weak_ptr_factory_.GetWeakPtr(),
99 src_file_path,
100 dest_file_path,
101 callback,
102 base::Owned(local_id)));
118 } 103 }
119 104
120 void MoveOperation::MoveAfterPrepare( 105 void MoveOperation::MoveAfterUpdateLocalState(
121 const MoveParams& params, 106 const base::FilePath& src_file_path,
122 scoped_ptr<ResourceEntry> src_entry, 107 const base::FilePath& dest_file_path,
123 scoped_ptr<ResourceEntry> src_parent_entry, 108 const FileOperationCallback& callback,
124 scoped_ptr<ResourceEntry> dest_parent_entry, 109 const std::string* local_id,
125 FileError error) { 110 FileError error) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127 DCHECK(!params.callback.is_null());
128
129 if (error != FILE_ERROR_OK) {
130 params.callback.Run(error);
131 return;
132 }
133
134 if (!dest_parent_entry->file_info().is_directory()) {
135 // The parent of the destination is not a directory.
136 params.callback.Run(FILE_ERROR_NOT_A_DIRECTORY);
137 return;
138 }
139
140 // Strip the extension for a hosted document if necessary.
141 const bool has_hosted_document_extension =
142 src_entry->has_file_specific_info() &&
143 src_entry->file_specific_info().is_hosted_document() &&
144 params.dest_file_path.Extension() ==
145 src_entry->file_specific_info().document_extension();
146 const std::string new_title =
147 has_hosted_document_extension ?
148 params.dest_file_path.BaseName().RemoveExtension().AsUTF8Unsafe() :
149 params.dest_file_path.BaseName().AsUTF8Unsafe();
150
151 base::Time last_modified =
152 params.preserve_last_modified ?
153 base::Time::FromInternalValue(src_entry->file_info().last_modified()) :
154 base::Time();
155
156 scheduler_->UpdateResource(
157 src_entry->resource_id(), dest_parent_entry->resource_id(),
158 new_title, last_modified, base::Time(),
159 base::Bind(&MoveOperation::MoveAfterUpdateResource,
160 weak_ptr_factory_.GetWeakPtr(), params));
161 }
162
163 void MoveOperation::MoveAfterUpdateResource(
164 const MoveParams& params,
165 google_apis::GDataErrorCode status,
166 scoped_ptr<google_apis::ResourceEntry> resource_entry) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168
169 const FileError error = GDataToFileError(status);
170 if (error != FILE_ERROR_OK) {
171 params.callback.Run(error);
172 return;
173 }
174
175 base::PostTaskAndReplyWithResult(
176 blocking_task_runner_.get(),
177 FROM_HERE,
178 base::Bind(&RefreshEntry, metadata_, base::Passed(&resource_entry)),
179 base::Bind(&MoveOperation::MoveAfterRefreshEntry,
180 weak_ptr_factory_.GetWeakPtr(), params));
181 }
182
183 void MoveOperation::MoveAfterRefreshEntry(const MoveParams& params,
184 FileError error) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
186 if (error == FILE_ERROR_OK) { 112 if (error == FILE_ERROR_OK) {
187 // Notify the change of directory. 113 // Notify the change of directory.
188 observer_->OnDirectoryChangedByOperation(params.src_file_path.DirName()); 114 observer_->OnDirectoryChangedByOperation(src_file_path.DirName());
189 observer_->OnDirectoryChangedByOperation(params.dest_file_path.DirName()); 115 observer_->OnDirectoryChangedByOperation(dest_file_path.DirName());
116 observer_->OnEntryUpdatedByOperation(*local_id);
190 } 117 }
191 118 callback.Run(error);
192 params.callback.Run(error);
193 } 119 }
194 120
195 } // namespace file_system 121 } // namespace file_system
196 } // namespace drive 122 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698