summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-08 14:41:08 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-08 14:41:08 +0000
commit6c116404c0e4ebcbfea94ff91e0979bee67222e4 (patch)
treec749a0f0f2f538ed7651da2f0cda4a5667cd8fcc /chrome/browser
parent6f45d5f57decad87b06a63239d77657ed458e361 (diff)
downloadchromium_src-6c116404c0e4ebcbfea94ff91e0979bee67222e4.zip
chromium_src-6c116404c0e4ebcbfea94ff91e0979bee67222e4.tar.gz
chromium_src-6c116404c0e4ebcbfea94ff91e0979bee67222e4.tar.bz2
Converted BookmarkStorage to use ImportantFileWriter
Also made BookmarkStorage completely responsible for migration of bookmark data from history database. Previously the logic crossed file and class boundaries a few times. This made it a bit hard to follow. Now it should be a bit more clear. Made ImportantFileWriter also batch data serializations. TEST=Make sure that bookmarks still work. Also test migrating bookmarks from history database. http://crbug.com/10618 Review URL: http://codereview.chromium.org/99192 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15635 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/bookmarks/bookmark_model.cc80
-rw-r--r--chrome/browser/bookmarks/bookmark_model.h23
-rw-r--r--chrome/browser/bookmarks/bookmark_storage.cc300
-rw-r--r--chrome/browser/bookmarks/bookmark_storage.h103
4 files changed, 242 insertions, 264 deletions
diff --git a/chrome/browser/bookmarks/bookmark_model.cc b/chrome/browser/bookmarks/bookmark_model.cc
index e944419..646aa3f 100644
--- a/chrome/browser/bookmarks/bookmark_model.cc
+++ b/chrome/browser/bookmarks/bookmark_model.cc
@@ -109,7 +109,6 @@ BookmarkModel::BookmarkModel(Profile* profile)
bookmark_bar_node_(NULL),
other_node_(NULL),
observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY),
- waiting_for_history_load_(false),
loaded_signal_(TRUE, FALSE)
{
// Create the bookmark bar and other bookmarks folders. These always exist.
@@ -135,11 +134,6 @@ BookmarkModel::~BookmarkModel() {
this, NotificationType::FAVICON_CHANGED, Source<Profile>(profile_));
}
- if (waiting_for_history_load_) {
- NotificationService::current()->RemoveObserver(
- this, NotificationType::HISTORY_LOADED, Source<Profile>(profile_));
- }
-
FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
BookmarkModelBeingDeleted(this));
@@ -167,7 +161,7 @@ void BookmarkModel::Load() {
// Load the bookmarks. BookmarkStorage notifies us when done.
store_ = new BookmarkStorage(profile_, this);
- store_->LoadBookmarks(false);
+ store_->LoadBookmarks();
}
BookmarkNode* BookmarkModel::GetParentForNewNodes() {
@@ -437,65 +431,9 @@ void BookmarkModel::RemoveNode(BookmarkNode* node,
RemoveNode(node->GetChild(i), removed_urls);
}
-void BookmarkModel::OnBookmarkStorageLoadedBookmarks(
- bool file_exists,
- bool loaded_from_history) {
- if (loaded_) {
- NOTREACHED();
- return;
- }
-
- LOG(INFO) << "Loaded bookmarks, file_exists=" << file_exists <<
- " from_history=" << loaded_from_history;
-
- if (file_exists || loaded_from_history || !profile_ ||
- !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) {
- // The file exists, we're loaded.
- DoneLoading();
-
- if (loaded_from_history) {
- // We were just populated from the historical file. Schedule a save so
- // that the main file is up to date.
- store_->ScheduleSave();
- }
- return;
- }
-
- // The file doesn't exist. This means one of two things:
- // 1. A clean profile.
- // 2. The user is migrating from an older version where bookmarks were saved
- // in history.
- // We assume step 2. If history had the bookmarks, history will write the
- // bookmarks to a file for us. We need to wait until history has finished
- // loading before reading from that file.
- HistoryService* history =
- profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
- if (!history->backend_loaded()) {
- // The backend isn't finished loading. Wait for it.
- LOG(INFO) << " waiting for history to finish";
-
- waiting_for_history_load_ = true;
- NotificationService::current()->AddObserver(
- this, NotificationType::HISTORY_LOADED, Source<Profile>(profile_));
- } else {
- OnHistoryDone();
- }
-}
-
-void BookmarkModel::OnHistoryDone() {
- if (loaded_) {
- NOTREACHED();
- return;
- }
-
- LOG(INFO) << " history done, reloading";
-
- // If the bookmarks were stored in the db the db will have migrated them to
- // a file now. Try loading from the file.
- store_->LoadBookmarks(true);
-}
-
void BookmarkModel::DoneLoading() {
+ DCHECK(!loaded_);
+
{
AutoLock url_lock(url_lock_);
// Update nodes_ordered_by_url_set_ from the nodes.
@@ -718,18 +656,6 @@ void BookmarkModel::Observe(NotificationType type,
break;
}
- case NotificationType::HISTORY_LOADED: {
- if (waiting_for_history_load_) {
- waiting_for_history_load_ = false;
- NotificationService::current()->RemoveObserver(
- this,NotificationType::HISTORY_LOADED, Source<Profile>(profile_));
- OnHistoryDone();
- } else {
- NOTREACHED();
- }
- break;
- }
-
default:
NOTREACHED();
break;
diff --git a/chrome/browser/bookmarks/bookmark_model.h b/chrome/browser/bookmarks/bookmark_model.h
index e406e27..4b987d9 100644
--- a/chrome/browser/bookmarks/bookmark_model.h
+++ b/chrome/browser/bookmarks/bookmark_model.h
@@ -339,24 +339,6 @@ class BookmarkModel : public NotificationObserver, public BookmarkService {
// This does NOT delete the node.
void RemoveNode(BookmarkNode* node, std::set<GURL>* removed_urls);
- // Callback from BookmarkStorage that it has finished loading. This method
- // may be hit twice. In particular, on construction BookmarkModel asks
- // BookmarkStorage to load the bookmarks. BookmarkStorage invokes this method
- // with loaded_from_history false and file_exists indicating whether the
- // bookmarks file exists. If the file doesn't exist, we query history. When
- // history calls us back (OnHistoryDone) we then ask BookmarkStorage to load
- // from the migration file. BookmarkStorage again invokes this method, but
- // with |loaded_from_history| true.
- void OnBookmarkStorageLoadedBookmarks(bool file_exists,
- bool loaded_from_history);
-
- // Used for migrating bookmarks from history to standalone file.
- //
- // Callback from history that it is done with an empty request. This is used
- // if there is no bookmarks file. Once done, we attempt to load from the
- // temporary file creating during migration.
- void OnHistoryDone();
-
// Invoked when loading is finished. Sets loaded_ and notifies observers.
void DoneLoading();
@@ -444,11 +426,6 @@ class BookmarkModel : public NotificationObserver, public BookmarkService {
// Reads/writes bookmarks to disk.
scoped_refptr<BookmarkStorage> store_;
- // Have we installed a listener on the NotificationService for
- // NOTIFY_HISTORY_LOADED? A listener is installed if the bookmarks file
- // doesn't exist and the history service hasn't finished loading.
- bool waiting_for_history_load_;
-
base::WaitableEvent loaded_signal_;
DISALLOW_COPY_AND_ASSIGN(BookmarkModel);
diff --git a/chrome/browser/bookmarks/bookmark_storage.cc b/chrome/browser/bookmarks/bookmark_storage.cc
index e529b43..7df18cd 100644
--- a/chrome/browser/bookmarks/bookmark_storage.cc
+++ b/chrome/browser/bookmarks/bookmark_storage.cc
@@ -9,172 +9,240 @@
#include "base/json_writer.h"
#include "base/message_loop.h"
#include "base/thread.h"
+#include "base/time.h"
#include "chrome/browser/bookmarks/bookmark_codec.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/json_value_serializer.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
namespace {
// Extension used for backup files (copy of main file created during startup).
const FilePath::CharType kBackupExtension[] = FILE_PATH_LITERAL("bak");
-// Extension for the temporary file. We write to the temp file than move to
-// kBookmarksFileName.
-const FilePath::CharType kTmpExtension[] = FILE_PATH_LITERAL("tmp");
-
// How often we save.
const int kSaveDelayMS = 2500;
+class BackupTask : public Task {
+ public:
+ explicit BackupTask(const FilePath& path) : path_(path) {
+ }
+
+ virtual void Run() {
+ FilePath backup_path = path_.ReplaceExtension(kBackupExtension);
+ file_util::CopyFile(path_, backup_path);
+ }
+
+ private:
+ const FilePath path_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackupTask);
+};
+
+class FileDeleteTask : public Task {
+ public:
+ explicit FileDeleteTask(const FilePath& path) : path_(path) {
+ }
+
+ virtual void Run() {
+ file_util::Delete(path_, true);
+ }
+
+ private:
+ const FilePath path_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDeleteTask);
+};
+
} // namespace
+class BookmarkStorage::LoadTask : public Task {
+ public:
+ LoadTask(const FilePath& path, MessageLoop* loop,
+ BookmarkStorage* storage)
+ : path_(path),
+ loop_(loop),
+ storage_(storage) {
+ }
+
+ virtual void Run() {
+ bool bookmark_file_exists = file_util::PathExists(path_);
+ Value* root = NULL;
+ if (bookmark_file_exists) {
+ JSONFileValueSerializer serializer(path_);
+ root = serializer.Deserialize(NULL);
+ }
+
+ // BookmarkStorage takes ownership of root.
+ if (loop_) {
+ loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ storage_.get(), &BookmarkStorage::OnLoadFinished,
+ bookmark_file_exists, path_, root));
+ } else {
+ storage_->OnLoadFinished(bookmark_file_exists, path_, root);
+ }
+ }
+
+ private:
+ const FilePath path_;
+ MessageLoop* loop_;
+ scoped_refptr<BookmarkStorage> storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(LoadTask);
+};
+
// BookmarkStorage -------------------------------------------------------------
BookmarkStorage::BookmarkStorage(Profile* profile, BookmarkModel* model)
- : model_(model),
- ALLOW_THIS_IN_INITIALIZER_LIST(save_factory_(this)),
- backend_thread_(g_browser_process->file_thread()) {
- FilePath path = profile->GetPath().Append(chrome::kBookmarksFileName);
- FilePath tmp_history_path =
- profile->GetPath().Append(chrome::kHistoryBookmarksFileName);
- backend_ = new BookmarkStorageBackend(path, tmp_history_path);
+ : profile_(profile),
+ model_(model),
+ backend_thread_(g_browser_process->file_thread()),
+ writer_(profile->GetPath().Append(chrome::kBookmarksFileName),
+ backend_thread_),
+ tmp_history_path_(
+ profile->GetPath().Append(chrome::kHistoryBookmarksFileName)) {
+ writer_.set_commit_interval(base::TimeDelta::FromMilliseconds(kSaveDelayMS));
+ RunTaskOnBackendThread(new BackupTask(writer_.path()));
+}
+
+BookmarkStorage::~BookmarkStorage() {
+ if (writer_.HasPendingWrite())
+ writer_.DoScheduledWrite();
+}
+
+void BookmarkStorage::LoadBookmarks() {
+ DoLoadBookmarks(writer_.path());
+}
+
+void BookmarkStorage::DoLoadBookmarks(const FilePath& path) {
+ Task* task = new LoadTask(path,
+ backend_thread() ? MessageLoop::current() : NULL,
+ this);
+ RunTaskOnBackendThread(task);
}
-void BookmarkStorage::LoadBookmarks(bool load_from_history) {
- if (!backend_thread()) {
- backend_->Read(scoped_refptr<BookmarkStorage>(this), NULL,
- load_from_history);
+void BookmarkStorage::MigrateFromHistory() {
+ // We need to wait until history has finished loading before reading
+ // from generated bookmarks file.
+ HistoryService* history =
+ profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
+ if (!history) {
+ // This happens in unit tests.
+ if (model_)
+ model_->DoneLoading();
+ return;
+ }
+ if (!history->backend_loaded()) {
+ // The backend isn't finished loading. Wait for it.
+ notification_registrar_.Add(this, NotificationType::HISTORY_LOADED,
+ Source<Profile>(profile_));
} else {
- backend_thread()->message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(backend_.get(), &BookmarkStorageBackend::Read,
- scoped_refptr<BookmarkStorage>(this),
- MessageLoop::current(), load_from_history));
+ OnHistoryFinishedWriting();
}
}
+void BookmarkStorage::OnHistoryFinishedWriting() {
+ notification_registrar_.Remove(this, NotificationType::HISTORY_LOADED,
+ Source<Profile>(profile_));
+
+ // This is used when migrating bookmarks data from database to file.
+ // History wrote the file for us, and now we want to load data from it.
+ DoLoadBookmarks(tmp_history_path_);
+}
+
void BookmarkStorage::ScheduleSave() {
- if (!backend_thread()) {
- SaveNow();
- } else if (save_factory_.empty()) {
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, save_factory_.NewRunnableMethod(&BookmarkStorage::SaveNow),
- kSaveDelayMS);
- }
+ writer_.ScheduleWrite(this);
}
void BookmarkStorage::BookmarkModelDeleted() {
- if (!save_factory_.empty()) {
- // There's a pending save. We need to save now as otherwise by the time
- // SaveNow is invoked the model is gone.
- save_factory_.RevokeAll();
+ // We need to save now as otherwise by the time SaveNow is invoked
+ // the model is gone.
+ if (writer_.HasPendingWrite())
SaveNow();
- }
model_ = NULL;
}
-void BookmarkStorage::LoadedBookmarks(Value* root_value,
- bool bookmark_file_exists,
- bool loaded_from_history) {
+bool BookmarkStorage::SerializeData(std::string* output) {
+ BookmarkCodec codec;
+ scoped_ptr<Value> value(codec.Encode(model_));
+ JSONStringValueSerializer serializer(output);
+ serializer.set_pretty_print(true);
+ return serializer.Serialize(*(value.get()));
+}
+
+void BookmarkStorage::OnLoadFinished(bool file_exists, const FilePath& path,
+ Value* root_value) {
scoped_ptr<Value> value_ref(root_value);
- if (model_) {
- if (root_value) {
- BookmarkCodec codec;
- codec.Decode(model_, *root_value);
- }
- model_->OnBookmarkStorageLoadedBookmarks(bookmark_file_exists,
- loaded_from_history);
+ if (path == writer_.path() && !file_exists) {
+ // The file doesn't exist. This means one of two things:
+ // 1. A clean profile.
+ // 2. The user is migrating from an older version where bookmarks were
+ // saved in history.
+ // We assume step 2. If history had the bookmarks, it will write the
+ // bookmarks to a file for us.
+ MigrateFromHistory();
+ return;
}
-}
-void BookmarkStorage::SaveNow() {
- if (!model_ || !model_->IsLoaded()) {
- // We should only get here if we have a valid model and it's finished
- // loading.
- NOTREACHED();
+ if (!model_)
return;
- }
- BookmarkCodec codec;
- Value* value = codec.Encode(model_);
- // The backend deletes value in write.
- if (!backend_thread()) {
- backend_->Write(value);
- } else {
- backend_thread()->message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(backend_.get(), &BookmarkStorageBackend::Write,
- value));
+ if (root_value) {
+ BookmarkCodec codec;
+ codec.Decode(model_, *root_value);
}
-}
-// BookmarkStorageBackend ------------------------------------------------------
+ model_->DoneLoading();
+
+ if (path == tmp_history_path_) {
+ // We just finished migration from history. Save now to new file,
+ // after the model is created and done loading.
+ SaveNow();
-BookmarkStorageBackend::BookmarkStorageBackend(
- const FilePath& path,
- const FilePath& tmp_history_path)
- : path_(path),
- tmp_history_path_(tmp_history_path) {
- // Make a backup of the current file.
- FilePath backup_path = path.ReplaceExtension(kBackupExtension);
- file_util::CopyFile(path, backup_path);
+ // Clean up after migration from history.
+ RunTaskOnBackendThread(new FileDeleteTask(tmp_history_path_));
+ }
}
-void BookmarkStorageBackend::Write(Value* value) {
- DCHECK(value);
-
- // We own Value.
- scoped_ptr<Value> value_ref(value);
-
- std::string content;
- JSONWriter::Write(value, true, &content);
-
- // Write to a temp file, then rename.
- FilePath tmp_file = path_.ReplaceExtension(kTmpExtension);
-
- int bytes_written = file_util::WriteFile(tmp_file, content.c_str(),
- static_cast<int>(content.length()));
- if (bytes_written != -1) {
- if (!file_util::Move(tmp_file, path_)) {
- // Rename failed. Try again on the off chance someone has locked either
- // file and hope we're successful the second time through.
- bool move_result = file_util::Move(tmp_file, path_);
- DCHECK(move_result);
- if (!move_result)
- LOG(WARNING) << " writing bookmarks failed, result=" << move_result;
- else
- LOG(INFO) << "wrote bookmarks, file=" << path_.value();
- } else {
- LOG(INFO) << "wrote bookmarks, file=" << path_.value();
- }
- // Nuke the history file so that we don't attempt to load from it again.
- file_util::Delete(tmp_history_path_, false);
- } else {
- LOG(WARNING) << " writing bookmarks failed, bytes written=" <<
- bytes_written;
+void BookmarkStorage::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::HISTORY_LOADED:
+ OnHistoryFinishedWriting();
+ break;
+
+ default:
+ NOTREACHED();
+ break;
}
}
-void BookmarkStorageBackend::Read(scoped_refptr<BookmarkStorage> service,
- MessageLoop* message_loop,
- bool load_from_history) {
- const FilePath& path = load_from_history ? tmp_history_path_ : path_;
- bool bookmark_file_exists = file_util::PathExists(path);
- Value* root = NULL;
- if (bookmark_file_exists) {
- JSONFileValueSerializer serializer(path);
- root = serializer.Deserialize(NULL);
+bool BookmarkStorage::SaveNow() {
+ if (!model_ || !model_->IsLoaded()) {
+ // We should only get here if we have a valid model and it's finished
+ // loading.
+ NOTREACHED();
+ return false;
}
- // BookmarkStorage takes ownership of root.
- if (message_loop) {
- message_loop->PostTask(FROM_HERE, NewRunnableMethod(
- service.get(), &BookmarkStorage::LoadedBookmarks, root,
- bookmark_file_exists, load_from_history));
+ std::string data;
+ if (!SerializeData(&data))
+ return false;
+ writer_.WriteNow(data);
+ return true;
+}
+
+void BookmarkStorage::RunTaskOnBackendThread(Task* task) const {
+ if (backend_thread()) {
+ backend_thread()->message_loop()->PostTask(FROM_HERE, task);
} else {
- service->LoadedBookmarks(root, bookmark_file_exists, load_from_history);
+ task->Run();
+ delete task;
}
}
diff --git a/chrome/browser/bookmarks/bookmark_storage.h b/chrome/browser/bookmarks/bookmark_storage.h
index 7048928..61162eb 100644
--- a/chrome/browser/bookmarks/bookmark_storage.h
+++ b/chrome/browser/bookmarks/bookmark_storage.h
@@ -7,12 +7,13 @@
#include "base/file_path.h"
#include "base/ref_counted.h"
-#include "base/task.h"
+#include "chrome/common/important_file_writer.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
class BookmarkModel;
-class BookmarkStorageBackend;
class Profile;
-class MessageLoop;
+class Task;
class Value;
namespace base {
@@ -24,18 +25,16 @@ class Thread;
// as notifying the BookmarkStorage every time the model changes.
//
// Internally BookmarkStorage uses BookmarkCodec to do the actual read/write.
-
-class BookmarkStorage : public base::RefCountedThreadSafe<BookmarkStorage> {
- friend class BookmarkStorageBackend;
-
+class BookmarkStorage : public NotificationObserver,
+ public ImportantFileWriter::DataSerializer,
+ public base::RefCountedThreadSafe<BookmarkStorage> {
public:
// Creates a BookmarkStorage for the specified model
BookmarkStorage(Profile* profile, BookmarkModel* model);
+ ~BookmarkStorage();
- // Loads the bookmarks into the model, notifying the model when done. If
- // load_from_history is true, the bookmarks are loaded from the file written
- // by history (StarredURLDatabase).
- void LoadBookmarks(bool load_from_history);
+ // Loads the bookmarks into the model, notifying the model when done.
+ void LoadBookmarks();
// Schedules saving the bookmark bar model to disk.
void ScheduleSave();
@@ -44,59 +43,67 @@ class BookmarkStorage : public base::RefCountedThreadSafe<BookmarkStorage> {
// a pending save, it is saved immediately.
void BookmarkModelDeleted();
+ // ImportantFileWriter::DataSerializer
+ virtual bool SerializeData(std::string* output);
+
private:
+ class LoadTask;
+
// Callback from backend with the results of the bookmark file.
- void LoadedBookmarks(Value* root_value,
- bool bookmark_file_exists,
- bool loaded_from_history);
+ // This may be called multiple times, with different paths. This happens when
+ // we migrate bookmark data from database.
+ void OnLoadFinished(bool file_exists, const FilePath& path,
+ Value* root_value);
- // Schedules a save on the backend thread.
- void SaveNow();
+ // Loads bookmark data from |file| and notifies the model when finished.
+ void DoLoadBookmarks(const FilePath& file);
- // Returns the thread the backend is run on.
- base::Thread* backend_thread() const { return backend_thread_; }
+ // Load bookmarks data from the file written by history (StarredURLDatabase).
+ void MigrateFromHistory();
- // The model. The model is NULL once BookmarkModelDeleted has been invoked.
- BookmarkModel* model_;
+ // Called when history has written the file with bookmarks data. Loads data
+ // from that file.
+ void OnHistoryFinishedWriting();
- // Used to delay saves.
- ScopedRunnableMethodFactory<BookmarkStorage> save_factory_;
+ // Called after we loaded file generated by history. Saves the data, deletes
+ // the temporary file, and notifies the model.
+ void FinishHistoryMigration();
- // The backend handles actual reading/writing to disk.
- scoped_refptr<BookmarkStorageBackend> backend_;
+ // NotificationObserver
+ void Observe(NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details);
- // Thread read/writing is run on. This comes from the profile, and is null
- // during testing.
- base::Thread* backend_thread_;
+ // Serializes the data and schedules save using ImportantFileWriter.
+ // Returns true on successful serialization.
+ bool SaveNow();
- DISALLOW_COPY_AND_ASSIGN(BookmarkStorage);
-};
+ // Runs task on backend thread (or on current thread if backend thread
+ // is NULL). Takes ownership of |task|.
+ void RunTaskOnBackendThread(Task* task) const;
-// Used to save the bookmarks on the file thread.
-class BookmarkStorageBackend :
- public base::RefCountedThreadSafe<BookmarkStorageBackend> {
- public:
- explicit BookmarkStorageBackend(const FilePath& path,
- const FilePath& tmp_history_path);
+ // Returns the thread the backend is run on.
+ const base::Thread* backend_thread() const { return backend_thread_; }
- // Writes the specified value to disk. This takes ownership of |value| and
- // deletes it when done.
- void Write(Value* value);
+ // Keep the pointer to profile, we may need it for migration from history.
+ Profile* profile_;
- // Reads the bookmarks from kBookmarksFileName. Notifies |service| with
- // the results on the specified MessageLoop.
- void Read(scoped_refptr<BookmarkStorage> service,
- MessageLoop* message_loop,
- bool load_from_history);
+ // The model. The model is NULL once BookmarkModelDeleted has been invoked.
+ BookmarkModel* model_;
- private:
- // Path we read/write to.
- const FilePath path_;
+ // Thread read/writing is run on. This comes from the profile, and is null
+ // during testing.
+ const base::Thread* backend_thread_;
+
+ // Helper to write bookmark data safely.
+ ImportantFileWriter writer_;
- // Path bookmarks are read from if asked to load from history file.
+ // Helper to ensure that we unregister from notifications on destruction.
+ NotificationRegistrar notification_registrar_;
+
+ // Path to temporary file created during migrating bookmarks from history.
const FilePath tmp_history_path_;
- DISALLOW_COPY_AND_ASSIGN(BookmarkStorageBackend);
+ DISALLOW_COPY_AND_ASSIGN(BookmarkStorage);
};
#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_STORAGE_H_