1 // Copyright 2014 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 #ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_ 6 #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_ 7 8 #include "base/callback_forward.h" 9 #include "base/files/file_path.h" 10 #include "base/files/important_file_writer.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_vector.h" 14 #include "components/bookmarks/browser/bookmark_node.h" 15 16 class BookmarkModel; 17 18 namespace base { 19 class SequencedTaskRunner; 20 } 21 22 namespace bookmarks { 23 24 class BookmarkIndex; 25 26 // A list of BookmarkPermanentNodes that owns them. 27 typedef ScopedVector<BookmarkPermanentNode> BookmarkPermanentNodeList; 28 29 // A callback that generates a BookmarkPermanentNodeList, given a max ID to 30 // use. The max ID argument will be updated after any new nodes have been 31 // created and assigned IDs. 32 typedef base::Callback<BookmarkPermanentNodeList(int64*)> LoadExtraCallback; 33 34 // BookmarkLoadDetails is used by BookmarkStorage when loading bookmarks. 35 // BookmarkModel creates a BookmarkLoadDetails and passes it (including 36 // ownership) to BookmarkStorage. BookmarkStorage loads the bookmarks (and 37 // index) in the background thread, then calls back to the BookmarkModel (on 38 // the main thread) when loading is done, passing ownership back to the 39 // BookmarkModel. While loading BookmarkModel does not maintain references to 40 // the contents of the BookmarkLoadDetails, this ensures we don't have any 41 // threading problems. 42 class BookmarkLoadDetails { 43 public: 44 BookmarkLoadDetails(BookmarkPermanentNode* bb_node, 45 BookmarkPermanentNode* other_folder_node, 46 BookmarkPermanentNode* mobile_folder_node, 47 const LoadExtraCallback& load_extra_callback, 48 BookmarkIndex* index, 49 int64 max_id); 50 ~BookmarkLoadDetails(); 51 52 void LoadExtraNodes(); 53 54 BookmarkPermanentNode* bb_node() { return bb_node_.get(); } 55 BookmarkPermanentNode* release_bb_node() { return bb_node_.release(); } 56 BookmarkPermanentNode* mobile_folder_node() { 57 return mobile_folder_node_.get(); 58 } 59 BookmarkPermanentNode* release_mobile_folder_node() { 60 return mobile_folder_node_.release(); 61 } 62 BookmarkPermanentNode* other_folder_node() { 63 return other_folder_node_.get(); 64 } 65 BookmarkPermanentNode* release_other_folder_node() { 66 return other_folder_node_.release(); 67 } 68 const BookmarkPermanentNodeList& extra_nodes() { 69 return extra_nodes_; 70 } 71 void release_extra_nodes(std::vector<BookmarkPermanentNode*>* extra_nodes) { 72 extra_nodes_.release(extra_nodes); 73 } 74 BookmarkIndex* index() { return index_.get(); } 75 BookmarkIndex* release_index() { return index_.release(); } 76 77 const BookmarkNode::MetaInfoMap& model_meta_info_map() const { 78 return model_meta_info_map_; 79 } 80 void set_model_meta_info_map(const BookmarkNode::MetaInfoMap& meta_info_map) { 81 model_meta_info_map_ = meta_info_map; 82 } 83 84 int64 model_sync_transaction_version() const { 85 return model_sync_transaction_version_; 86 } 87 void set_model_sync_transaction_version(int64 sync_transaction_version) { 88 model_sync_transaction_version_ = sync_transaction_version; 89 } 90 91 // Max id of the nodes. 92 void set_max_id(int64 max_id) { max_id_ = max_id; } 93 int64 max_id() const { return max_id_; } 94 95 // Computed checksum. 96 void set_computed_checksum(const std::string& value) { 97 computed_checksum_ = value; 98 } 99 const std::string& computed_checksum() const { return computed_checksum_; } 100 101 // Stored checksum. 102 void set_stored_checksum(const std::string& value) { 103 stored_checksum_ = value; 104 } 105 const std::string& stored_checksum() const { return stored_checksum_; } 106 107 // Whether ids were reassigned. IDs are reassigned during decoding if the 108 // checksum of the file doesn't match, some IDs are missing or not 109 // unique. Basically, if the user modified the bookmarks directly we'll 110 // reassign the ids to ensure they are unique. 111 void set_ids_reassigned(bool value) { ids_reassigned_ = value; } 112 bool ids_reassigned() const { return ids_reassigned_; } 113 114 private: 115 scoped_ptr<BookmarkPermanentNode> bb_node_; 116 scoped_ptr<BookmarkPermanentNode> other_folder_node_; 117 scoped_ptr<BookmarkPermanentNode> mobile_folder_node_; 118 LoadExtraCallback load_extra_callback_; 119 BookmarkPermanentNodeList extra_nodes_; 120 scoped_ptr<BookmarkIndex> index_; 121 BookmarkNode::MetaInfoMap model_meta_info_map_; 122 int64 model_sync_transaction_version_; 123 int64 max_id_; 124 std::string computed_checksum_; 125 std::string stored_checksum_; 126 bool ids_reassigned_; 127 128 DISALLOW_COPY_AND_ASSIGN(BookmarkLoadDetails); 129 }; 130 131 // BookmarkStorage handles reading/write the bookmark bar model. The 132 // BookmarkModel uses the BookmarkStorage to load bookmarks from disk, as well 133 // as notifying the BookmarkStorage every time the model changes. 134 // 135 // Internally BookmarkStorage uses BookmarkCodec to do the actual read/write. 136 class BookmarkStorage : public base::ImportantFileWriter::DataSerializer, 137 public base::RefCountedThreadSafe<BookmarkStorage> { 138 public: 139 // Creates a BookmarkStorage for the specified model. The data will be loaded 140 // from and saved to a location derived from |profile_path|. The IO code will 141 // be executed as a task in |sequenced_task_runner|. 142 BookmarkStorage(BookmarkModel* model, 143 const base::FilePath& profile_path, 144 base::SequencedTaskRunner* sequenced_task_runner); 145 146 // Loads the bookmarks into the model, notifying the model when done. This 147 // takes ownership of |details| and send the |OnLoadFinished| callback from 148 // a task in |task_runner|. See BookmarkLoadDetails for details. 149 void LoadBookmarks( 150 scoped_ptr<BookmarkLoadDetails> details, 151 const scoped_refptr<base::SequencedTaskRunner>& task_runner); 152 153 // Schedules saving the bookmark bar model to disk. 154 void ScheduleSave(); 155 156 // Notification the bookmark bar model is going to be deleted. If there is 157 // a pending save, it is saved immediately. 158 void BookmarkModelDeleted(); 159 160 // Callback from backend after loading the bookmark file. 161 void OnLoadFinished(); 162 163 // ImportantFileWriter::DataSerializer implementation. 164 virtual bool SerializeData(std::string* output) OVERRIDE; 165 166 private: 167 friend class base::RefCountedThreadSafe<BookmarkStorage>; 168 169 virtual ~BookmarkStorage(); 170 171 // Serializes the data and schedules save using ImportantFileWriter. 172 // Returns true on successful serialization. 173 bool SaveNow(); 174 175 // The model. The model is NULL once BookmarkModelDeleted has been invoked. 176 BookmarkModel* model_; 177 178 // Helper to write bookmark data safely. 179 base::ImportantFileWriter writer_; 180 181 // See class description of BookmarkLoadDetails for details on this. 182 scoped_ptr<BookmarkLoadDetails> details_; 183 184 // Sequenced task runner where file I/O operations will be performed at. 185 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; 186 187 DISALLOW_COPY_AND_ASSIGN(BookmarkStorage); 188 }; 189 190 } // namespace bookmarks 191 192 #endif // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_ 193