| Index: components/safe_browsing_db/v4_database.cc
|
| diff --git a/components/safe_browsing_db/v4_database.cc b/components/safe_browsing_db/v4_database.cc
|
| index 99a22468e0c1fd58896fe46f6ad483ac76d58b4e..a64ad48d5d0f0e9cea1d40d149c775597aed144e 100644
|
| --- a/components/safe_browsing_db/v4_database.cc
|
| +++ b/components/safe_browsing_db/v4_database.cc
|
| @@ -23,16 +23,16 @@ void V4Database::Create(
|
| const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
|
| const base::FilePath& base_path,
|
| const StoreFileNameMap& store_file_name_map,
|
| - NewDatabaseReadyCallback callback) {
|
| - // Create the database, which may be a lengthy operation, on the
|
| - // db_task_runner, but once that is done, call the caller back on this
|
| - // thread.
|
| + NewDatabaseReadyCallback new_db_callback) {
|
| + DCHECK(base_path.IsAbsolute());
|
| + DCHECK(!store_file_name_map.empty());
|
| +
|
| const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner =
|
| base::MessageLoop::current()->task_runner();
|
| db_task_runner->PostTask(
|
| FROM_HERE,
|
| base::Bind(&V4Database::CreateOnTaskRunner, db_task_runner, base_path,
|
| - store_file_name_map, callback_task_runner, callback));
|
| + store_file_name_map, callback_task_runner, new_db_callback));
|
| }
|
|
|
| // static
|
| @@ -41,15 +41,15 @@ void V4Database::CreateOnTaskRunner(
|
| const base::FilePath& base_path,
|
| const StoreFileNameMap& store_file_name_map,
|
| const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
|
| - NewDatabaseReadyCallback callback) {
|
| + NewDatabaseReadyCallback new_db_callback) {
|
| DCHECK(db_task_runner->RunsTasksOnCurrentThread());
|
| - DCHECK(base_path.IsAbsolute());
|
|
|
| if (!factory_) {
|
| factory_ = new V4StoreFactory();
|
| ANNOTATE_LEAKING_OBJECT_PTR(factory_);
|
| }
|
| - auto store_map = base::MakeUnique<StoreMap>();
|
| +
|
| + std::unique_ptr<StoreMap> store_map = base::MakeUnique<StoreMap>();
|
| for (const auto& store_info : store_file_name_map) {
|
| const UpdateListIdentifier& update_list_identifier = store_info.first;
|
| const base::FilePath store_path = base_path.AppendASCII(store_info.second);
|
| @@ -59,15 +59,18 @@ void V4Database::CreateOnTaskRunner(
|
| std::unique_ptr<V4Database> v4_database(
|
| new V4Database(db_task_runner, std::move(store_map)));
|
|
|
| - // Database is done loading, pass it to the callback on the caller's thread.
|
| + // Database is done loading, pass it to the new_db_callback on the caller's
|
| + // thread.
|
| callback_task_runner->PostTask(
|
| - FROM_HERE, base::Bind(callback, base::Passed(&v4_database)));
|
| + FROM_HERE, base::Bind(new_db_callback, base::Passed(&v4_database)));
|
| }
|
|
|
| V4Database::V4Database(
|
| const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
|
| std::unique_ptr<StoreMap> store_map)
|
| - : db_task_runner_(db_task_runner), store_map_(std::move(store_map)) {
|
| + : db_task_runner_(db_task_runner),
|
| + store_map_(std::move(store_map)),
|
| + pending_store_updates_(0) {
|
| DCHECK(db_task_runner->RunsTasksOnCurrentThread());
|
| // TODO(vakh): Implement skeleton
|
| }
|
| @@ -84,15 +87,75 @@ V4Database::~V4Database() {
|
| DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
|
| }
|
|
|
| +void V4Database::ApplyUpdate(const std::vector<ListUpdateResponse>& responses,
|
| + DatabaseUpdatedCallback db_updated_callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(!pending_store_updates_);
|
| + DCHECK(db_updated_callback_.is_null());
|
| +
|
| + db_updated_callback_ = db_updated_callback;
|
| +
|
| + // Post the V4Store update task on the task runner but get the callback on the
|
| + // current thread.
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& current_task_runner =
|
| + base::MessageLoop::current()->task_runner();
|
| + for (const ListUpdateResponse& response : responses) {
|
| + UpdateListIdentifier identifier(response);
|
| + StoreMap::const_iterator iter = store_map_->find(identifier);
|
| + if (iter != store_map_->end()) {
|
| + const std::unique_ptr<V4Store>& old_store = iter->second;
|
| + if (old_store->state() != response.new_client_state()) {
|
| + // A different state implies there are updates to process.
|
| + pending_store_updates_++;
|
| + UpdatedStoreReadyCallback store_ready_callback = base::Bind(
|
| + &V4Database::UpdatedStoreReady, base::Unretained(this), identifier);
|
| + db_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&V4Store::ApplyUpdate, base::Unretained(old_store.get()),
|
| + response, current_task_runner, store_ready_callback));
|
| + }
|
| + } else {
|
| + NOTREACHED() << "Got update for unexpected identifier: " << identifier;
|
| + }
|
| + }
|
| +
|
| + if (!pending_store_updates_) {
|
| + current_task_runner->PostTask(FROM_HERE, db_updated_callback_);
|
| + db_updated_callback_.Reset();
|
| + }
|
| +}
|
| +
|
| +void V4Database::UpdatedStoreReady(UpdateListIdentifier identifier,
|
| + std::unique_ptr<V4Store> new_store) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(pending_store_updates_);
|
| + (*store_map_)[identifier] = std::move(new_store);
|
| +
|
| + pending_store_updates_--;
|
| + if (!pending_store_updates_) {
|
| + db_updated_callback_.Run();
|
| + db_updated_callback_.Reset();
|
| + }
|
| +}
|
| +
|
| bool V4Database::ResetDatabase() {
|
| DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
|
| bool reset_success = true;
|
| - for (const auto& store_id_and_store : *store_map_) {
|
| - if (!store_id_and_store.second->Reset()) {
|
| + for (const auto& store_map_iter : *store_map_) {
|
| + if (!store_map_iter.second->Reset()) {
|
| reset_success = false;
|
| }
|
| }
|
| return reset_success;
|
| }
|
|
|
| +std::unique_ptr<StoreStateMap> V4Database::GetStoreStateMap() {
|
| + std::unique_ptr<StoreStateMap> store_state_map =
|
| + base::MakeUnique<StoreStateMap>();
|
| + for (const auto& store_map_iter : *store_map_) {
|
| + (*store_state_map)[store_map_iter.first] = store_map_iter.second->state();
|
| + }
|
| + return store_state_map;
|
| +}
|
| +
|
| } // namespace safe_browsing
|
|
|