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

Side by Side Diff: components/drive/chromeos/change_list_processor.cc

Issue 2799603002: Process TeamDrive change in change list. (Closed)
Patch Set: Avoid crash when receiving TD deletion entry. Created 3 years, 8 months 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
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 "components/drive/chromeos/change_list_processor.h" 5 #include "components/drive/chromeos/change_list_processor.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/synchronization/cancellation_flag.h" 15 #include "base/synchronization/cancellation_flag.h"
16 #include "components/drive/chromeos/resource_metadata.h" 16 #include "components/drive/chromeos/resource_metadata.h"
17 #include "components/drive/drive.pb.h" 17 #include "components/drive/drive.pb.h"
18 #include "components/drive/drive_api_util.h" 18 #include "components/drive/drive_api_util.h"
19 #include "components/drive/file_change.h" 19 #include "components/drive/file_change.h"
20 #include "components/drive/file_system_core_util.h" 20 #include "components/drive/file_system_core_util.h"
21 #include "components/drive/resource_entry_conversion.h" 21 #include "components/drive/resource_entry_conversion.h"
22 #include "google_apis/drive/drive_api_parser.h" 22 #include "google_apis/drive/drive_api_parser.h"
23 #include "google_apis/drive/drive_switches.h"
23 24
24 namespace drive { 25 namespace drive {
25 namespace internal { 26 namespace internal {
26 27
27 namespace { 28 namespace {
28 29
29 class ChangeListToEntryMapUMAStats { 30 class ChangeListToEntryMapUMAStats {
30 public: 31 public:
31 ChangeListToEntryMapUMAStats() 32 ChangeListToEntryMapUMAStats()
32 : num_regular_files_(0), 33 : num_regular_files_(0),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 71 }
71 72
72 ChangeList::ChangeList() {} 73 ChangeList::ChangeList() {}
73 74
74 ChangeList::ChangeList(const google_apis::ChangeList& change_list) 75 ChangeList::ChangeList(const google_apis::ChangeList& change_list)
75 : next_url_(change_list.next_link()), 76 : next_url_(change_list.next_link()),
76 largest_changestamp_(change_list.largest_change_id()) { 77 largest_changestamp_(change_list.largest_change_id()) {
77 const std::vector<std::unique_ptr<google_apis::ChangeResource>>& items = 78 const std::vector<std::unique_ptr<google_apis::ChangeResource>>& items =
78 change_list.items(); 79 change_list.items();
79 entries_.resize(items.size()); 80 entries_.resize(items.size());
81 team_drives_.resize(items.size());
80 parent_resource_ids_.resize(items.size()); 82 parent_resource_ids_.resize(items.size());
81 size_t entries_index = 0; 83 size_t entries_index = 0;
84 size_t team_drives_index = 0;
82 for (size_t i = 0; i < items.size(); ++i) { 85 for (size_t i = 0; i < items.size(); ++i) {
83 if (ConvertChangeResourceToResourceEntry( 86 if (items[i]->type() == google_apis::ChangeResource::TEAM_DRIVE) {
hashimoto 2017/04/07 07:56:41 Can't we do this check in ConvertTeamDriveChangeRe
yamaguchi 2017/04/07 15:31:46 Done.
84 *items[i], 87 if (ConvertTeamDriveChangeResourceToResourceEntry(
85 &entries_[entries_index], 88 *items[i], &team_drives_[team_drives_index])) {
86 &parent_resource_ids_[entries_index])) { 89 ++team_drives_index;
90 }
91 } else if (ConvertChangeResourceToResourceEntry(
92 *items[i], &entries_[entries_index],
93 &parent_resource_ids_[entries_index])) {
87 ++entries_index; 94 ++entries_index;
88 } 95 }
89 } 96 }
90 entries_.resize(entries_index); 97 entries_.resize(entries_index);
98 team_drives_.resize(team_drives_index);
91 parent_resource_ids_.resize(entries_index); 99 parent_resource_ids_.resize(entries_index);
92 } 100 }
93 101
94 ChangeList::ChangeList(const google_apis::FileList& file_list) 102 ChangeList::ChangeList(const google_apis::FileList& file_list)
95 : next_url_(file_list.next_link()), 103 : next_url_(file_list.next_link()),
96 largest_changestamp_(0) { 104 largest_changestamp_(0) {
97 const std::vector<std::unique_ptr<google_apis::FileResource>>& items = 105 const std::vector<std::unique_ptr<google_apis::FileResource>>& items =
98 file_list.items(); 106 file_list.items();
99 entries_.resize(items.size()); 107 entries_.resize(items.size());
100 parent_resource_ids_.resize(items.size()); 108 parent_resource_ids_.resize(items.size());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 150
143 DVLOG(1) << "Root folder ID is " << about_resource->root_folder_id(); 151 DVLOG(1) << "Root folder ID is " << about_resource->root_folder_id();
144 DCHECK(!about_resource->root_folder_id().empty()); 152 DCHECK(!about_resource->root_folder_id().empty());
145 } 153 }
146 154
147 // Convert ChangeList to map. 155 // Convert ChangeList to map.
148 ChangeListToEntryMapUMAStats uma_stats; 156 ChangeListToEntryMapUMAStats uma_stats;
149 for (size_t i = 0; i < change_lists.size(); ++i) { 157 for (size_t i = 0; i < change_lists.size(); ++i) {
150 ChangeList* change_list = change_lists[i].get(); 158 ChangeList* change_list = change_lists[i].get();
151 159
160 const std::vector<ResourceEntry>& team_drives = change_list->team_drives();
161 for (size_t i = 0; i < team_drives.size(); ++i) {
162 if (team_drives.at(i).deleted())
163 // TODO(yamaguchi): Handle deleting change of Team Drives. Deletion
164 // entries of Team Drive should be filtered in ApplyEntryMap().
165 continue;
166 ApplyTeamDriveChange(team_drives.at(i));
167 }
168
152 std::vector<ResourceEntry>* entries = change_list->mutable_entries(); 169 std::vector<ResourceEntry>* entries = change_list->mutable_entries();
153 for (size_t i = 0; i < entries->size(); ++i) { 170 for (size_t i = 0; i < entries->size(); ++i) {
154 ResourceEntry* entry = &(*entries)[i]; 171 ResourceEntry* entry = &(*entries)[i];
155 172
156 // Count the number of files. 173 // Count the number of files.
157 if (!entry->file_info().is_directory()) { 174 if (!entry->file_info().is_directory()) {
158 uma_stats.IncrementNumFiles( 175 uma_stats.IncrementNumFiles(
159 entry->file_specific_info().is_hosted_document()); 176 entry->file_specific_info().is_hosted_document());
160 } 177 }
161 parent_resource_id_map_[entry->resource_id()] = 178 parent_resource_id_map_[entry->resource_id()] =
(...skipping 27 matching lines...) Expand all
189 return error; 206 return error;
190 } 207 }
191 208
192 // Shouldn't record histograms when processing delta update. 209 // Shouldn't record histograms when processing delta update.
193 if (!is_delta_update) 210 if (!is_delta_update)
194 uma_stats.UpdateFileCountUmaHistograms(); 211 uma_stats.UpdateFileCountUmaHistograms();
195 212
196 return FILE_ERROR_OK; 213 return FILE_ERROR_OK;
197 } 214 }
198 215
216 FileError ChangeListProcessor::ApplyTeamDriveChange(
217 const ResourceEntry& change) {
218 parent_resource_id_map_[change.resource_id()] =
219 util::kDriveTeamDrivesDirVirtualResourceId;
220 return ApplyEntry(change);
221 }
222
199 FileError ChangeListProcessor::ApplyEntryMap( 223 FileError ChangeListProcessor::ApplyEntryMap(
200 int64_t changestamp, 224 int64_t changestamp,
201 std::unique_ptr<google_apis::AboutResource> about_resource) { 225 std::unique_ptr<google_apis::AboutResource> about_resource) {
202 DCHECK(about_resource); 226 DCHECK(about_resource);
203 227
204 // Create the entry for "My Drive" directory with the latest changestamp. 228 // Create the entry for "My Drive" directory with the latest changestamp.
205 ResourceEntry root; 229 ResourceEntry root;
206 FileError error = resource_metadata_->GetResourceEntryByPath( 230 FileError error = resource_metadata_->GetResourceEntryByPath(
207 util::GetDriveMyDriveRootPath(), &root); 231 util::GetDriveMyDriveRootPath(), &root);
208 if (error != FILE_ERROR_OK) { 232 if (error != FILE_ERROR_OK) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 } 325 }
302 } 326 }
303 it = it_parent; 327 it = it_parent;
304 } 328 }
305 329
306 // Apply the parent first. 330 // Apply the parent first.
307 std::reverse(entries.begin(), entries.end()); 331 std::reverse(entries.begin(), entries.end());
308 for (size_t i = 0; i < entries.size(); ++i) { 332 for (size_t i = 0; i < entries.size(); ++i) {
309 // Skip root entry in the change list. We don't expect servers to send 333 // Skip root entry in the change list. We don't expect servers to send
310 // root entry, but we should better be defensive (see crbug.com/297259). 334 // root entry, but we should better be defensive (see crbug.com/297259).
335 // TODO(yamaguchi): Apply this defensive logic to root directories of
336 // every Team Drive as well.
311 ResourceEntryMap::iterator it = entries[i]; 337 ResourceEntryMap::iterator it = entries[i];
312 if (it->first != root.resource_id()) { 338 if (it->first != root.resource_id()) {
313 FileError error = ApplyEntry(it->second); 339 FileError error = ApplyEntry(it->second);
314 if (error != FILE_ERROR_OK) { 340 if (error != FILE_ERROR_OK) {
315 LOG(ERROR) << "ApplyEntry failed: " << FileErrorToString(error) 341 LOG(ERROR) << "ApplyEntry failed: " << FileErrorToString(error)
316 << ", title = " << it->second.title(); 342 << ", title = " << it->second.title();
317 return error; 343 return error;
318 } 344 }
319 } 345 }
320 entry_map_.erase(it); 346 entry_map_.erase(it);
(...skipping 20 matching lines...) Expand all
341 << ", resource_id = " << deleted_resource_ids[i]; 367 << ", resource_id = " << deleted_resource_ids[i];
342 return error; 368 return error;
343 } 369 }
344 } 370 }
345 371
346 return FILE_ERROR_OK; 372 return FILE_ERROR_OK;
347 } 373 }
348 374
349 FileError ChangeListProcessor::ApplyEntry(const ResourceEntry& entry) { 375 FileError ChangeListProcessor::ApplyEntry(const ResourceEntry& entry) {
350 DCHECK(!entry.deleted()); 376 DCHECK(!entry.deleted());
377 DCHECK(!entry.resource_id().empty());
351 DCHECK(parent_resource_id_map_.count(entry.resource_id())); 378 DCHECK(parent_resource_id_map_.count(entry.resource_id()));
352 const std::string& parent_resource_id = 379 const std::string& parent_resource_id =
353 parent_resource_id_map_[entry.resource_id()]; 380 parent_resource_id_map_[entry.resource_id()];
354 381
355 ResourceEntry new_entry(entry); 382 ResourceEntry new_entry(entry);
356 FileError error = SetParentLocalIdOfEntry(resource_metadata_, &new_entry, 383 FileError error = SetParentLocalIdOfEntry(resource_metadata_, &new_entry,
357 parent_resource_id); 384 parent_resource_id);
358 if (error != FILE_ERROR_OK) 385 if (error != FILE_ERROR_OK)
359 return error; 386 return error;
360 387
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 489
463 // static 490 // static
464 FileError ChangeListProcessor::SetParentLocalIdOfEntry( 491 FileError ChangeListProcessor::SetParentLocalIdOfEntry(
465 ResourceMetadata* resource_metadata, 492 ResourceMetadata* resource_metadata,
466 ResourceEntry* entry, 493 ResourceEntry* entry,
467 const std::string& parent_resource_id) { 494 const std::string& parent_resource_id) {
468 std::string parent_local_id; 495 std::string parent_local_id;
469 if (parent_resource_id.empty()) { 496 if (parent_resource_id.empty()) {
470 // Entries without parents should go under "other" directory. 497 // Entries without parents should go under "other" directory.
471 parent_local_id = util::kDriveOtherDirLocalId; 498 parent_local_id = util::kDriveOtherDirLocalId;
499 } else if (parent_resource_id == util::kDriveTeamDrivesDirVirtualResourceId) {
hashimoto 2017/04/07 07:56:41 Instead of introducing this "virtual resource ID",
yamaguchi 2017/04/07 15:31:46 Changed to insert the virtual resource ID to the "
hashimoto 2017/04/10 11:01:23 The idea of "virtual resource ID" sounds awkward t
yamaguchi 2017/04/11 07:08:07 Thanks. Now I think it should work without introdu
500 parent_local_id = util::kDriveTeamDrivesDirLocalId;
472 } else { 501 } else {
473 FileError error = resource_metadata->GetIdByResourceId( 502 FileError error = resource_metadata->GetIdByResourceId(
474 parent_resource_id, &parent_local_id); 503 parent_resource_id, &parent_local_id);
475 if (error != FILE_ERROR_OK) 504 if (error != FILE_ERROR_OK)
476 return error; 505 return error;
477 } 506 }
478 entry->set_parent_local_id(parent_local_id); 507 entry->set_parent_local_id(parent_local_id);
479 return FILE_ERROR_OK; 508 return FILE_ERROR_OK;
480 } 509 }
481 510
482 void ChangeListProcessor::UpdateChangedDirs(const ResourceEntry& entry) { 511 void ChangeListProcessor::UpdateChangedDirs(const ResourceEntry& entry) {
483 DCHECK(!entry.resource_id().empty()); 512 DCHECK(!entry.resource_id().empty());
484 513
485 std::string local_id; 514 std::string local_id;
486 base::FilePath file_path; 515 base::FilePath file_path;
487 if (resource_metadata_->GetIdByResourceId( 516 if (resource_metadata_->GetIdByResourceId(
488 entry.resource_id(), &local_id) == FILE_ERROR_OK) 517 entry.resource_id(), &local_id) == FILE_ERROR_OK)
489 resource_metadata_->GetFilePath(local_id, &file_path); 518 resource_metadata_->GetFilePath(local_id, &file_path);
490 519
491 if (!file_path.empty()) { 520 if (!file_path.empty()) {
492 FileChange::ChangeType type = entry.deleted() 521 FileChange::ChangeType type = entry.deleted()
493 ? FileChange::CHANGE_TYPE_DELETE 522 ? FileChange::CHANGE_TYPE_DELETE
494 : FileChange::CHANGE_TYPE_ADD_OR_UPDATE; 523 : FileChange::CHANGE_TYPE_ADD_OR_UPDATE;
495 changed_files_->Update(file_path, entry, type); 524 changed_files_->Update(file_path, entry, type);
496 } 525 }
497 } 526 }
498 527
499 } // namespace internal 528 } // namespace internal
500 } // namespace drive 529 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698