1// Copyright (c) 2011 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 CHROME_BROWSER_BOOKMARKS_BOOKMARK_STORAGE_H_
6#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_STORAGE_H_
7
8#include "base/files/important_file_writer.h"
9#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_ptr.h"
11
12class BookmarkIndex;
13class BookmarkModel;
14class BookmarkPermanentNode;
15
16namespace base {
17class SequencedTaskRunner;
18}
19
20namespace content {
21class BrowserContext;
22}
23
24// BookmarkLoadDetails is used by BookmarkStorage when loading bookmarks.
25// BookmarkModel creates a BookmarkLoadDetails and passes it (including
26// ownership) to BookmarkStorage. BookmarkStorage loads the bookmarks (and
27// index) in the background thread, then calls back to the BookmarkModel (on
28// the main thread) when loading is done, passing ownership back to the
29// BookmarkModel. While loading BookmarkModel does not maintain references to
30// the contents of the BookmarkLoadDetails, this ensures we don't have any
31// threading problems.
32class BookmarkLoadDetails {
33 public:
34  BookmarkLoadDetails(BookmarkPermanentNode* bb_node,
35                      BookmarkPermanentNode* other_folder_node,
36                      BookmarkPermanentNode* mobile_folder_node,
37                      BookmarkIndex* index,
38                      int64 max_id);
39  ~BookmarkLoadDetails();
40
41  BookmarkPermanentNode* bb_node() { return bb_node_.get(); }
42  BookmarkPermanentNode* release_bb_node() { return bb_node_.release(); }
43  BookmarkPermanentNode* mobile_folder_node() {
44    return mobile_folder_node_.get();
45  }
46  BookmarkPermanentNode* release_mobile_folder_node() {
47    return mobile_folder_node_.release();
48  }
49  BookmarkPermanentNode* other_folder_node() {
50    return other_folder_node_.get();
51  }
52  BookmarkPermanentNode* release_other_folder_node() {
53    return other_folder_node_.release();
54  }
55  BookmarkIndex* index() { return index_.get(); }
56  BookmarkIndex* release_index() { return index_.release(); }
57
58  const std::string& model_meta_info() { return model_meta_info_; }
59  void set_model_meta_info(const std::string& meta_info) {
60    model_meta_info_ = meta_info;
61  }
62
63  // Max id of the nodes.
64  void set_max_id(int64 max_id) { max_id_ = max_id; }
65  int64 max_id() const { return max_id_; }
66
67  // Computed checksum.
68  void set_computed_checksum(const std::string& value) {
69    computed_checksum_ = value;
70  }
71  const std::string& computed_checksum() const { return computed_checksum_; }
72
73  // Stored checksum.
74  void set_stored_checksum(const std::string& value) {
75    stored_checksum_ = value;
76  }
77  const std::string& stored_checksum() const { return stored_checksum_; }
78
79  // Whether ids were reassigned. IDs are reassigned during decoding if the
80  // checksum of the file doesn't match, some IDs are missing or not
81  // unique. Basically, if the user modified the bookmarks directly we'll
82  // reassign the ids to ensure they are unique.
83  void set_ids_reassigned(bool value) { ids_reassigned_ = value; }
84  bool ids_reassigned() const { return ids_reassigned_; }
85
86 private:
87  scoped_ptr<BookmarkPermanentNode> bb_node_;
88  scoped_ptr<BookmarkPermanentNode> other_folder_node_;
89  scoped_ptr<BookmarkPermanentNode> mobile_folder_node_;
90  scoped_ptr<BookmarkIndex> index_;
91  std::string model_meta_info_;
92  int64 max_id_;
93  std::string computed_checksum_;
94  std::string stored_checksum_;
95  bool ids_reassigned_;
96
97  DISALLOW_COPY_AND_ASSIGN(BookmarkLoadDetails);
98};
99
100// BookmarkStorage handles reading/write the bookmark bar model. The
101// BookmarkModel uses the BookmarkStorage to load bookmarks from disk, as well
102// as notifying the BookmarkStorage every time the model changes.
103//
104// Internally BookmarkStorage uses BookmarkCodec to do the actual read/write.
105class BookmarkStorage : public base::ImportantFileWriter::DataSerializer,
106                        public base::RefCountedThreadSafe<BookmarkStorage> {
107 public:
108  // Creates a BookmarkStorage for the specified model
109  BookmarkStorage(content::BrowserContext* context,
110                  BookmarkModel* model,
111                  base::SequencedTaskRunner* sequenced_task_runner);
112
113  // Loads the bookmarks into the model, notifying the model when done. This
114  // takes ownership of |details|. See BookmarkLoadDetails for details.
115  void LoadBookmarks(BookmarkLoadDetails* details);
116
117  // Schedules saving the bookmark bar model to disk.
118  void ScheduleSave();
119
120  // Notification the bookmark bar model is going to be deleted. If there is
121  // a pending save, it is saved immediately.
122  void BookmarkModelDeleted();
123
124  // Callback from backend after loading the bookmark file.
125  void OnLoadFinished();
126
127  // ImportantFileWriter::DataSerializer implementation.
128  virtual bool SerializeData(std::string* output) OVERRIDE;
129
130 private:
131  friend class base::RefCountedThreadSafe<BookmarkStorage>;
132
133  virtual ~BookmarkStorage();
134
135  // Serializes the data and schedules save using ImportantFileWriter.
136  // Returns true on successful serialization.
137  bool SaveNow();
138
139  // The model. The model is NULL once BookmarkModelDeleted has been invoked.
140  BookmarkModel* model_;
141
142  // Helper to write bookmark data safely.
143  base::ImportantFileWriter writer_;
144
145  // See class description of BookmarkLoadDetails for details on this.
146  scoped_ptr<BookmarkLoadDetails> details_;
147
148  // Sequenced task runner where file I/O operations will be performed at.
149  scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
150
151  DISALLOW_COPY_AND_ASSIGN(BookmarkStorage);
152};
153
154#endif  // CHROME_BROWSER_BOOKMARKS_BOOKMARK_STORAGE_H_
155