// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_ #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_ #include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/files/important_file_writer.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "components/bookmarks/browser/bookmark_node.h" namespace base { class SequencedTaskRunner; } namespace bookmarks { class BookmarkIndex; class BookmarkModel; // A list of BookmarkPermanentNodes that owns them. typedef ScopedVector BookmarkPermanentNodeList; // A callback that generates a BookmarkPermanentNodeList, given a max ID to // use. The max ID argument will be updated after any new nodes have been // created and assigned IDs. typedef base::Callback LoadExtraCallback; // BookmarkLoadDetails is used by BookmarkStorage when loading bookmarks. // BookmarkModel creates a BookmarkLoadDetails and passes it (including // ownership) to BookmarkStorage. BookmarkStorage loads the bookmarks (and // index) in the background thread, then calls back to the BookmarkModel (on // the main thread) when loading is done, passing ownership back to the // BookmarkModel. While loading BookmarkModel does not maintain references to // the contents of the BookmarkLoadDetails, this ensures we don't have any // threading problems. class BookmarkLoadDetails { public: BookmarkLoadDetails(BookmarkPermanentNode* bb_node, BookmarkPermanentNode* other_folder_node, BookmarkPermanentNode* mobile_folder_node, const LoadExtraCallback& load_extra_callback, BookmarkIndex* index, int64 max_id); ~BookmarkLoadDetails(); void LoadExtraNodes(); BookmarkPermanentNode* bb_node() { return bb_node_.get(); } BookmarkPermanentNode* release_bb_node() { return bb_node_.release(); } BookmarkPermanentNode* mobile_folder_node() { return mobile_folder_node_.get(); } BookmarkPermanentNode* release_mobile_folder_node() { return mobile_folder_node_.release(); } BookmarkPermanentNode* other_folder_node() { return other_folder_node_.get(); } BookmarkPermanentNode* release_other_folder_node() { return other_folder_node_.release(); } const BookmarkPermanentNodeList& extra_nodes() { return extra_nodes_; } void release_extra_nodes(std::vector* extra_nodes) { extra_nodes_.release(extra_nodes); } BookmarkIndex* index() { return index_.get(); } BookmarkIndex* release_index() { return index_.release(); } const BookmarkNode::MetaInfoMap& model_meta_info_map() const { return model_meta_info_map_; } void set_model_meta_info_map(const BookmarkNode::MetaInfoMap& meta_info_map) { model_meta_info_map_ = meta_info_map; } int64 model_sync_transaction_version() const { return model_sync_transaction_version_; } void set_model_sync_transaction_version(int64 sync_transaction_version) { model_sync_transaction_version_ = sync_transaction_version; } // Max id of the nodes. void set_max_id(int64 max_id) { max_id_ = max_id; } int64 max_id() const { return max_id_; } // Computed checksum. void set_computed_checksum(const std::string& value) { computed_checksum_ = value; } const std::string& computed_checksum() const { return computed_checksum_; } // Stored checksum. void set_stored_checksum(const std::string& value) { stored_checksum_ = value; } const std::string& stored_checksum() const { return stored_checksum_; } // Whether ids were reassigned. IDs are reassigned during decoding if the // checksum of the file doesn't match, some IDs are missing or not // unique. Basically, if the user modified the bookmarks directly we'll // reassign the ids to ensure they are unique. void set_ids_reassigned(bool value) { ids_reassigned_ = value; } bool ids_reassigned() const { return ids_reassigned_; } private: scoped_ptr bb_node_; scoped_ptr other_folder_node_; scoped_ptr mobile_folder_node_; LoadExtraCallback load_extra_callback_; BookmarkPermanentNodeList extra_nodes_; scoped_ptr index_; BookmarkNode::MetaInfoMap model_meta_info_map_; int64 model_sync_transaction_version_; int64 max_id_; std::string computed_checksum_; std::string stored_checksum_; bool ids_reassigned_; DISALLOW_COPY_AND_ASSIGN(BookmarkLoadDetails); }; // BookmarkStorage handles reading/write the bookmark bar model. The // BookmarkModel uses the BookmarkStorage to load bookmarks from disk, as well // as notifying the BookmarkStorage every time the model changes. // // Internally BookmarkStorage uses BookmarkCodec to do the actual read/write. class BookmarkStorage : public base::ImportantFileWriter::DataSerializer { public: // Creates a BookmarkStorage for the specified model. The data will be loaded // from and saved to a location derived from |profile_path|. The IO code will // be executed as a task in |sequenced_task_runner|. BookmarkStorage(BookmarkModel* model, const base::FilePath& profile_path, base::SequencedTaskRunner* sequenced_task_runner); ~BookmarkStorage() override; // Loads the bookmarks into the model, notifying the model when done. This // takes ownership of |details| and send the |OnLoadFinished| callback from // a task in |task_runner|. See BookmarkLoadDetails for details. void LoadBookmarks( scoped_ptr details, const scoped_refptr& task_runner); // Schedules saving the bookmark bar model to disk. void ScheduleSave(); // Notification the bookmark bar model is going to be deleted. If there is // a pending save, it is saved immediately. void BookmarkModelDeleted(); // Callback from backend after loading the bookmark file. void OnLoadFinished(scoped_ptr details); // ImportantFileWriter::DataSerializer implementation. bool SerializeData(std::string* output) override; private: // Serializes the data and schedules save using ImportantFileWriter. // Returns true on successful serialization. bool SaveNow(); // The model. The model is NULL once BookmarkModelDeleted has been invoked. BookmarkModel* model_; // Helper to write bookmark data safely. base::ImportantFileWriter writer_; // Sequenced task runner where file I/O operations will be performed at. scoped_refptr sequenced_task_runner_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(BookmarkStorage); }; } // namespace bookmarks #endif // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_STORAGE_H_