OLD | NEW |
---|---|
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/gdata/gdata_files.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_files.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/platform_file.h" | 9 #include "base/platform_file.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "base/sequenced_task_runner.h" | |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 14 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
14 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 15 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
15 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" | 16 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" |
17 #include "content/public/browser/browser_thread.h" | |
16 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
17 | 19 |
20 using content::BrowserThread; | |
21 | |
18 namespace gdata { | 22 namespace gdata { |
19 namespace { | 23 namespace { |
20 | 24 |
21 const char kSlash[] = "/"; | 25 const char kSlash[] = "/"; |
22 const char kEscapedSlash[] = "\xE2\x88\x95"; | 26 const char kEscapedSlash[] = "\xE2\x88\x95"; |
23 | 27 |
24 // Extracts resource_id out of edit url. | 28 // Extracts resource_id out of edit url. |
25 std::string ExtractResourceId(const GURL& url) { | 29 std::string ExtractResourceId(const GURL& url) { |
26 return net::UnescapeURLComponent(url.ExtractFileName(), | 30 return net::UnescapeURLComponent(url.ExtractFileName(), |
27 net::UnescapeRule::URL_SPECIAL_CHARS); | 31 net::UnescapeRule::URL_SPECIAL_CHARS); |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 if (directory_service_) | 434 if (directory_service_) |
431 directory_service_->RemoveEntryFromResourceMap(dir); | 435 directory_service_->RemoveEntryFromResourceMap(dir); |
432 } | 436 } |
433 STLDeleteValues(&child_directories_); | 437 STLDeleteValues(&child_directories_); |
434 child_directories_.clear(); | 438 child_directories_.clear(); |
435 } | 439 } |
436 | 440 |
437 // GDataDirectoryService class implementation. | 441 // GDataDirectoryService class implementation. |
438 | 442 |
439 GDataDirectoryService::GDataDirectoryService() | 443 GDataDirectoryService::GDataDirectoryService() |
440 : serialized_size_(0), | 444 : blocking_task_runner_(NULL), |
445 serialized_size_(0), | |
441 largest_changestamp_(0), | 446 largest_changestamp_(0), |
442 origin_(UNINITIALIZED) { | 447 origin_(UNINITIALIZED) { |
443 root_.reset(new GDataDirectory(NULL, this)); | 448 root_.reset(new GDataDirectory(NULL, this)); |
444 root_->set_title(kGDataRootDirectory); | 449 root_->set_title(kGDataRootDirectory); |
445 root_->SetBaseNameFromTitle(); | 450 root_->SetBaseNameFromTitle(); |
446 root_->set_resource_id(kGDataRootDirectoryResourceId); | 451 root_->set_resource_id(kGDataRootDirectoryResourceId); |
447 AddEntryToResourceMap(root_.get()); | 452 AddEntryToResourceMap(root_.get()); |
448 } | 453 } |
449 | 454 |
450 GDataDirectoryService::~GDataDirectoryService() { | 455 GDataDirectoryService::~GDataDirectoryService() { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 | 534 |
530 void GDataDirectoryService::RefreshFile(scoped_ptr<GDataFile> fresh_file) { | 535 void GDataDirectoryService::RefreshFile(scoped_ptr<GDataFile> fresh_file) { |
531 DCHECK(fresh_file.get()); | 536 DCHECK(fresh_file.get()); |
532 | 537 |
533 // Need to get a reference here because Passed() could get evaluated first. | 538 // Need to get a reference here because Passed() could get evaluated first. |
534 const std::string& resource_id = fresh_file->resource_id(); | 539 const std::string& resource_id = fresh_file->resource_id(); |
535 GetEntryByResourceIdAsync(resource_id, | 540 GetEntryByResourceIdAsync(resource_id, |
536 base::Bind(&RefreshFileInternal, base::Passed(&fresh_file))); | 541 base::Bind(&RefreshFileInternal, base::Passed(&fresh_file))); |
537 } | 542 } |
538 | 543 |
544 void GDataDirectoryService::InitFromDB( | |
545 const FilePath& db_path, | |
546 base::SequencedTaskRunner* blocking_task_runner) { | |
547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
548 DCHECK(!db_path.empty()); | |
549 DCHECK(blocking_task_runner); | |
550 | |
551 db_path_ = db_path; | |
552 blocking_task_runner_ = blocking_task_runner; | |
553 | |
554 SerializedMap* serialized_resources(new SerializedMap); | |
555 blocking_task_runner_->PostTaskAndReply( | |
556 FROM_HERE, | |
557 base::Bind(&GDataDirectoryService::ReadFromDBOnBlockingThread, | |
558 base::Unretained(this), | |
559 db_path, | |
560 serialized_resources), | |
561 base::Bind(&GDataDirectoryService::InitResourceMapOnUIThread, | |
562 base::Unretained(this), | |
hashimoto
2012/07/24 08:41:51
Is this Unretained safe?
satorux1
2012/07/24 16:30:34
should use WeakPtr here.
| |
563 base::Owned(serialized_resources))); | |
satorux1
2012/07/24 16:30:34
Seems to me that initialization from the DB is sig
| |
564 } | |
565 | |
566 void GDataDirectoryService::ReadFromDBOnBlockingThread( | |
567 const FilePath& db_path, | |
568 SerializedMap* serialized_resources) { | |
569 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | |
570 InitDBOnBlockingThread(db_path); | |
571 | |
572 if (serialized_resources) { | |
573 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( | |
574 leveldb::ReadOptions())); | |
575 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { | |
576 serialized_resources->insert(std::make_pair(iter->key().ToString(), | |
577 iter->value().ToString())); | |
578 } | |
579 } | |
580 } | |
581 | |
582 void GDataDirectoryService::InitDBOnBlockingThread(const FilePath& db_path) { | |
583 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | |
584 DCHECK(!db_path.empty()); | |
585 | |
586 db_path_ = db_path; | |
587 leveldb::DB* level_db = NULL; | |
588 leveldb::Options options; | |
589 options.create_if_missing = true; | |
590 leveldb::Status db_status = leveldb::DB::Open(options, db_path.value(), | |
591 &level_db); | |
592 DCHECK(level_db); | |
593 DCHECK(db_status.ok()); | |
594 level_db_.reset(level_db); | |
595 } | |
596 | |
597 void GDataDirectoryService::InitResourceMapOnUIThread( | |
598 SerializedMap* serialized_resources) { | |
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
600 DCHECK(resource_map_.empty()); | |
601 | |
602 ResourceMap resource_map; | |
603 for (SerializedMap::const_iterator iter = serialized_resources->begin(); | |
604 iter != serialized_resources->end(); ++iter) { | |
605 scoped_ptr<GDataEntry> entry = GDataEntry::FromProtoString(iter->second); | |
606 resource_map.insert(std::make_pair(iter->first, entry.release())); | |
607 } | |
608 | |
609 // Fix up parent-child relations. | |
610 for (ResourceMap::iterator iter = resource_map.begin(); | |
611 iter != resource_map.end(); ++iter) { | |
612 GDataEntry* entry = iter->second; | |
613 ResourceMap::iterator parent_it = | |
614 resource_map.find(entry->parent_resource_id()); | |
615 if (parent_it != resource_map.end()) { | |
616 GDataDirectory* parent = parent_it->second->AsGDataDirectory(); | |
617 if (parent) { | |
618 parent->AddEntry(entry); | |
619 } else { | |
620 NOTREACHED() << "Parent is not a directory " << parent->resource_id(); | |
621 } | |
622 } else { | |
623 NOTREACHED() << "Missing parent id " << entry->parent_resource_id(); | |
624 } | |
625 } | |
626 } | |
627 | |
628 void GDataDirectoryService::SaveResourceMapToDB() { | |
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
630 SerializedMap serialized_resources; | |
631 for (ResourceMap::const_iterator iter = resource_map_.begin(); | |
632 iter != resource_map_.end(); ++iter) { | |
633 GDataEntryProto proto; | |
634 iter->second->ToProtoFull(&proto); | |
635 std::string serialized_string; | |
636 const bool ok = proto.SerializeToString(&serialized_string); | |
637 DCHECK(ok); | |
638 if (ok) { | |
639 serialized_resources.insert( | |
640 std::make_pair(iter->first, serialized_string)); | |
641 } | |
642 } | |
643 blocking_task_runner_->PostTask( | |
644 FROM_HERE, | |
645 base::Bind(&GDataDirectoryService::SaveSerializedToDBOnBlockingThread, | |
646 base::Unretained(this), | |
647 serialized_resources)); | |
648 } | |
649 | |
650 void GDataDirectoryService::SaveSerializedToDBOnBlockingThread( | |
651 const SerializedMap& serialized_resources) { | |
652 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | |
653 | |
654 // Truncate the DB. | |
655 level_db_.reset(); | |
656 leveldb::DestroyDB(db_path_.value(), leveldb::Options()); | |
657 InitDBOnBlockingThread(db_path_); | |
658 | |
659 for (SerializedMap::const_iterator iter = serialized_resources.begin(); | |
660 iter != serialized_resources.end(); ++iter) { | |
661 level_db_->Put(leveldb::WriteOptions(), | |
662 leveldb::Slice(iter->first), | |
663 leveldb::Slice(iter->second)); | |
664 } | |
665 } | |
666 | |
539 // Convert to/from proto. | 667 // Convert to/from proto. |
540 | 668 |
541 // static | 669 // static |
542 void GDataEntry::ConvertProtoToPlatformFileInfo( | 670 void GDataEntry::ConvertProtoToPlatformFileInfo( |
543 const PlatformFileInfoProto& proto, | 671 const PlatformFileInfoProto& proto, |
544 base::PlatformFileInfo* file_info) { | 672 base::PlatformFileInfo* file_info) { |
545 file_info->size = proto.size(); | 673 file_info->size = proto.size(); |
546 file_info->is_directory = proto.is_directory(); | 674 file_info->is_directory = proto.is_directory(); |
547 file_info->is_symbolic_link = proto.is_symbolic_link(); | 675 file_info->is_symbolic_link = proto.is_symbolic_link(); |
548 file_info->last_modified = base::Time::FromInternalValue( | 676 file_info->last_modified = base::Time::FromInternalValue( |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
764 if (!root_->FromProto(proto.gdata_directory())) | 892 if (!root_->FromProto(proto.gdata_directory())) |
765 return false; | 893 return false; |
766 | 894 |
767 origin_ = FROM_CACHE; | 895 origin_ = FROM_CACHE; |
768 largest_changestamp_ = proto.largest_changestamp(); | 896 largest_changestamp_ = proto.largest_changestamp(); |
769 | 897 |
770 return true; | 898 return true; |
771 } | 899 } |
772 | 900 |
773 } // namespace gdata | 901 } // namespace gdata |
OLD | NEW |