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