Home | History | Annotate | Download | only in common
      1 // Copyright 2013 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 #include "chrome/browser/ui/app_list/search/common/dictionary_data_store.h"
      6 
      7 #include "base/callback.h"
      8 #include "base/json/json_file_value_serializer.h"
      9 #include "base/json/json_string_value_serializer.h"
     10 #include "base/logging.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/task_runner_util.h"
     13 #include "base/threading/sequenced_worker_pool.h"
     14 #include "base/values.h"
     15 #include "content/public/browser/browser_thread.h"
     16 
     17 using content::BrowserThread;
     18 
     19 namespace app_list {
     20 
     21 DictionaryDataStore::DictionaryDataStore(const base::FilePath& data_file)
     22     : data_file_(data_file) {
     23   std::string token("app-launcher-data-store");
     24   token.append(data_file.AsUTF8Unsafe());
     25 
     26   // Uses a SKIP_ON_SHUTDOWN file task runner because losing a couple
     27   // associations is better than blocking shutdown.
     28   base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
     29   file_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior(
     30       pool->GetNamedSequenceToken(token),
     31       base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
     32   writer_.reset(
     33       new base::ImportantFileWriter(data_file, file_task_runner_.get()));
     34 
     35   cached_dict_.reset(new base::DictionaryValue);
     36 }
     37 
     38 DictionaryDataStore::~DictionaryDataStore() {
     39   Flush(OnFlushedCallback());
     40 }
     41 
     42 void DictionaryDataStore::Flush(const OnFlushedCallback& on_flushed) {
     43   if (writer_->HasPendingWrite())
     44     writer_->DoScheduledWrite();
     45 
     46   if (on_flushed.is_null())
     47     return;
     48 
     49   file_task_runner_->PostTaskAndReply(
     50       FROM_HERE, base::Bind(&base::DoNothing), on_flushed);
     51 }
     52 
     53 void DictionaryDataStore::Load(
     54     const DictionaryDataStore::OnLoadedCallback& on_loaded) {
     55   base::PostTaskAndReplyWithResult(
     56       file_task_runner_.get(),
     57       FROM_HERE,
     58       base::Bind(&DictionaryDataStore::LoadOnBlockingPool, this),
     59       on_loaded);
     60 }
     61 
     62 void DictionaryDataStore::ScheduleWrite() {
     63   writer_->ScheduleWrite(this);
     64 }
     65 
     66 scoped_ptr<base::DictionaryValue> DictionaryDataStore::LoadOnBlockingPool() {
     67   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
     68 
     69   int error_code = JSONFileValueSerializer::JSON_NO_ERROR;
     70   std::string error_message;
     71   JSONFileValueSerializer serializer(data_file_);
     72   base::Value* value = serializer.Deserialize(&error_code, &error_message);
     73   base::DictionaryValue* dict_value = NULL;
     74   if (error_code != JSONFileValueSerializer::JSON_NO_ERROR ||
     75       !value ||
     76       !value->GetAsDictionary(&dict_value) ||
     77       !dict_value) {
     78     return scoped_ptr<base::DictionaryValue>();
     79   }
     80 
     81   base::DictionaryValue* return_dict = dict_value->DeepCopy();
     82   cached_dict_.reset(dict_value);
     83   return make_scoped_ptr(return_dict).Pass();
     84 }
     85 
     86 bool DictionaryDataStore::SerializeData(std::string* data) {
     87   JSONStringValueSerializer serializer(data);
     88   serializer.set_pretty_print(true);
     89   return serializer.Serialize(*cached_dict_.get());
     90 }
     91 
     92 }  // namespace app_list
     93