Moved JsonPrefStore to use SequencedWorkerPool instead of FILE thread. The pool also ensures that the same file requests are written in order received and that they block on shutdown.
BUG=153367 TEST=existing unit/browser tests Review URL: https://codereview.chromium.org/11027070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166603 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
base
files
prefs
chrome
browser
automation
bookmarks
browser_process_impl.ccbrowser_process_impl.hchrome_browser_main.ccchromeos
extensions
extension_prefs_unittest.ccextension_prefs_unittest.hextension_service_unittest.ccmenu_manager_unittest.cctest_extension_prefs.cctest_extension_prefs.h
updater
metrics
policy
prefs
pref_service.ccpref_service.hpref_service_mock_builder.ccpref_service_mock_builder.hpref_service_unittest.cc
profiles
sync
ui
views
bookmarks
service
cloud_print
service_process.ccservice_process.hservice_process_prefs.ccservice_process_prefs.hservice_process_prefs_unittest.cctest
chrome_frame/test/net
@@ -13,7 +13,7 @@
|
|||||||
#include "base/file_path.h"
|
#include "base/file_path.h"
|
||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/message_loop_proxy.h"
|
#include "base/task_runner.h"
|
||||||
#include "base/metrics/histogram.h"
|
#include "base/metrics/histogram.h"
|
||||||
#include "base/string_number_conversions.h"
|
#include "base/string_number_conversions.h"
|
||||||
#include "base/threading/thread.h"
|
#include "base/threading/thread.h"
|
||||||
@@ -90,14 +90,14 @@ void WriteToDiskTask(const FilePath& path, const std::string& data) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImportantFileWriter::ImportantFileWriter(
|
ImportantFileWriter::ImportantFileWriter(
|
||||||
const FilePath& path, MessageLoopProxy* file_message_loop_proxy)
|
const FilePath& path, base::SequencedTaskRunner* task_runner)
|
||||||
: path_(path),
|
: path_(path),
|
||||||
file_message_loop_proxy_(file_message_loop_proxy),
|
task_runner_(task_runner),
|
||||||
serializer_(NULL),
|
serializer_(NULL),
|
||||||
commit_interval_(TimeDelta::FromMilliseconds(
|
commit_interval_(TimeDelta::FromMilliseconds(
|
||||||
kDefaultCommitIntervalMs)) {
|
kDefaultCommitIntervalMs)) {
|
||||||
DCHECK(CalledOnValidThread());
|
DCHECK(CalledOnValidThread());
|
||||||
DCHECK(file_message_loop_proxy_.get());
|
DCHECK(task_runner_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportantFileWriter::~ImportantFileWriter() {
|
ImportantFileWriter::~ImportantFileWriter() {
|
||||||
@@ -122,8 +122,8 @@ void ImportantFileWriter::WriteNow(const std::string& data) {
|
|||||||
if (HasPendingWrite())
|
if (HasPendingWrite())
|
||||||
timer_.Stop();
|
timer_.Stop();
|
||||||
|
|
||||||
if (!file_message_loop_proxy_->PostTask(
|
if (!task_runner_->PostTask(FROM_HERE,
|
||||||
FROM_HERE, MakeCriticalClosure(Bind(&WriteToDiskTask, path_, data)))) {
|
MakeCriticalClosure(Bind(&WriteToDiskTask, path_, data)))) {
|
||||||
// Posting the task to background message loop is not expected
|
// Posting the task to background message loop is not expected
|
||||||
// to fail, but if it does, avoid losing data and just hit the disk
|
// to fail, but if it does, avoid losing data and just hit the disk
|
||||||
// on the current thread.
|
// on the current thread.
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
class MessageLoopProxy;
|
class SequencedTaskRunner;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
// Helper to ensure that a file won't be corrupted by the write (for example on
|
// Helper to ensure that a file won't be corrupted by the write (for example on
|
||||||
@@ -53,11 +53,11 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe {
|
|||||||
|
|
||||||
// Initialize the writer.
|
// Initialize the writer.
|
||||||
// |path| is the name of file to write.
|
// |path| is the name of file to write.
|
||||||
// |file_message_loop_proxy| is the MessageLoopProxy for a thread on which
|
// |task_runner| is the SequencedTaskRunner instance where on which we will
|
||||||
// file I/O can be done.
|
// execute file I/O operations.
|
||||||
// All non-const methods, ctor and dtor must be called on the same thread.
|
// All non-const methods, ctor and dtor must be called on the same thread.
|
||||||
ImportantFileWriter(const FilePath& path,
|
ImportantFileWriter(const FilePath& path,
|
||||||
MessageLoopProxy* file_message_loop_proxy);
|
base::SequencedTaskRunner* task_runner);
|
||||||
|
|
||||||
// You have to ensure that there are no pending writes at the moment
|
// You have to ensure that there are no pending writes at the moment
|
||||||
// of destruction.
|
// of destruction.
|
||||||
@@ -96,8 +96,8 @@ class BASE_EXPORT ImportantFileWriter : public NonThreadSafe {
|
|||||||
// Path being written to.
|
// Path being written to.
|
||||||
const FilePath path_;
|
const FilePath path_;
|
||||||
|
|
||||||
// MessageLoopProxy for the thread on which file I/O can be done.
|
// TaskRunner for the thread on which file I/O can be done.
|
||||||
scoped_refptr<MessageLoopProxy> file_message_loop_proxy_;
|
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||||
|
|
||||||
// Timer used to schedule commit after ScheduleWrite.
|
// Timer used to schedule commit after ScheduleWrite.
|
||||||
OneShotTimer<ImportantFileWriter> timer_;
|
OneShotTimer<ImportantFileWriter> timer_;
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
#include "base/json/json_string_value_serializer.h"
|
#include "base/json/json_string_value_serializer.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/message_loop_proxy.h"
|
#include "base/message_loop_proxy.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -26,25 +28,25 @@ class FileThreadDeserializer
|
|||||||
: public base::RefCountedThreadSafe<FileThreadDeserializer> {
|
: public base::RefCountedThreadSafe<FileThreadDeserializer> {
|
||||||
public:
|
public:
|
||||||
FileThreadDeserializer(JsonPrefStore* delegate,
|
FileThreadDeserializer(JsonPrefStore* delegate,
|
||||||
base::MessageLoopProxy* file_loop_proxy)
|
base::SequencedTaskRunner* sequenced_task_runner)
|
||||||
: no_dir_(false),
|
: no_dir_(false),
|
||||||
error_(PersistentPrefStore::PREF_READ_ERROR_NONE),
|
error_(PersistentPrefStore::PREF_READ_ERROR_NONE),
|
||||||
delegate_(delegate),
|
delegate_(delegate),
|
||||||
file_loop_proxy_(file_loop_proxy),
|
sequenced_task_runner_(sequenced_task_runner),
|
||||||
origin_loop_proxy_(base::MessageLoopProxy::current()) {
|
origin_loop_proxy_(base::MessageLoopProxy::current()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Start(const FilePath& path) {
|
void Start(const FilePath& path) {
|
||||||
DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
|
DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
|
||||||
file_loop_proxy_->PostTask(
|
sequenced_task_runner_->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
base::Bind(&FileThreadDeserializer::ReadFileAndReport,
|
base::Bind(&FileThreadDeserializer::ReadFileAndReport,
|
||||||
this, path));
|
this, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserializes JSON on the file thread.
|
// Deserializes JSON on the sequenced task runner.
|
||||||
void ReadFileAndReport(const FilePath& path) {
|
void ReadFileAndReport(const FilePath& path) {
|
||||||
DCHECK(file_loop_proxy_->BelongsToCurrentThread());
|
DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread());
|
||||||
|
|
||||||
value_.reset(DoReading(path, &error_, &no_dir_));
|
value_.reset(DoReading(path, &error_, &no_dir_));
|
||||||
|
|
||||||
@@ -84,9 +86,9 @@ class FileThreadDeserializer
|
|||||||
bool no_dir_;
|
bool no_dir_;
|
||||||
PersistentPrefStore::PrefReadError error_;
|
PersistentPrefStore::PrefReadError error_;
|
||||||
scoped_ptr<Value> value_;
|
scoped_ptr<Value> value_;
|
||||||
scoped_refptr<JsonPrefStore> delegate_;
|
const scoped_refptr<JsonPrefStore> delegate_;
|
||||||
scoped_refptr<base::MessageLoopProxy> file_loop_proxy_;
|
const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
|
||||||
scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
|
const scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -98,7 +100,8 @@ void FileThreadDeserializer::HandleErrors(
|
|||||||
PersistentPrefStore::PrefReadError* error) {
|
PersistentPrefStore::PrefReadError* error) {
|
||||||
*error = PersistentPrefStore::PREF_READ_ERROR_NONE;
|
*error = PersistentPrefStore::PREF_READ_ERROR_NONE;
|
||||||
if (!value) {
|
if (!value) {
|
||||||
DVLOG(1) << "Error while loading JSON file: " << error_msg;
|
DVLOG(1) << "Error while loading JSON file: " << error_msg
|
||||||
|
<< ", file: " << path.value();
|
||||||
switch (error_code) {
|
switch (error_code) {
|
||||||
case JSONFileValueSerializer::JSON_ACCESS_DENIED:
|
case JSONFileValueSerializer::JSON_ACCESS_DENIED:
|
||||||
*error = PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED;
|
*error = PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED;
|
||||||
@@ -137,13 +140,23 @@ void FileThreadDeserializer::HandleErrors(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile(
|
||||||
|
const FilePath& filename,
|
||||||
|
base::SequencedWorkerPool* worker_pool) {
|
||||||
|
std::string token("json_pref_store-");
|
||||||
|
token.append(filename.AsUTF8Unsafe());
|
||||||
|
return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
|
||||||
|
worker_pool->GetNamedSequenceToken(token),
|
||||||
|
base::SequencedWorkerPool::BLOCK_SHUTDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
JsonPrefStore::JsonPrefStore(const FilePath& filename,
|
JsonPrefStore::JsonPrefStore(const FilePath& filename,
|
||||||
base::MessageLoopProxy* file_message_loop_proxy)
|
base::SequencedTaskRunner* sequenced_task_runner)
|
||||||
: path_(filename),
|
: path_(filename),
|
||||||
file_message_loop_proxy_(file_message_loop_proxy),
|
sequenced_task_runner_(sequenced_task_runner),
|
||||||
prefs_(new DictionaryValue()),
|
prefs_(new DictionaryValue()),
|
||||||
read_only_(false),
|
read_only_(false),
|
||||||
writer_(filename, file_message_loop_proxy),
|
writer_(filename, sequenced_task_runner),
|
||||||
error_delegate_(NULL),
|
error_delegate_(NULL),
|
||||||
initialized_(false),
|
initialized_(false),
|
||||||
read_error_(PREF_READ_ERROR_OTHER) {
|
read_error_(PREF_READ_ERROR_OTHER) {
|
||||||
@@ -245,7 +258,7 @@ void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) {
|
|||||||
// Start async reading of the preferences file. It will delete itself
|
// Start async reading of the preferences file. It will delete itself
|
||||||
// in the end.
|
// in the end.
|
||||||
scoped_refptr<FileThreadDeserializer> deserializer(
|
scoped_refptr<FileThreadDeserializer> deserializer(
|
||||||
new FileThreadDeserializer(this, file_message_loop_proxy_.get()));
|
new FileThreadDeserializer(this, sequenced_task_runner_.get()));
|
||||||
deserializer->Start(path_);
|
deserializer->Start(path_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class DictionaryValue;
|
class DictionaryValue;
|
||||||
class MessageLoopProxy;
|
class SequencedWorkerPool;
|
||||||
|
class SequencedTaskRunner;
|
||||||
class Value;
|
class Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,10 +32,16 @@ class BASE_PREFS_EXPORT JsonPrefStore
|
|||||||
: public PersistentPrefStore,
|
: public PersistentPrefStore,
|
||||||
public base::ImportantFileWriter::DataSerializer {
|
public base::ImportantFileWriter::DataSerializer {
|
||||||
public:
|
public:
|
||||||
// |file_message_loop_proxy| is the MessageLoopProxy for a thread on which
|
// Returns instance of SequencedTaskRunner which guarantees that file
|
||||||
// file I/O can be done.
|
// operations on the same file will be executed in sequenced order.
|
||||||
|
static scoped_refptr<base::SequencedTaskRunner> GetTaskRunnerForFile(
|
||||||
|
const FilePath& pref_filename,
|
||||||
|
base::SequencedWorkerPool* worker_pool);
|
||||||
|
|
||||||
|
// |sequenced_task_runner| is must be a shutdown-blocking task runner, ideally
|
||||||
|
// created by GetTaskRunnerForFile() method above.
|
||||||
JsonPrefStore(const FilePath& pref_filename,
|
JsonPrefStore(const FilePath& pref_filename,
|
||||||
base::MessageLoopProxy* file_message_loop_proxy);
|
base::SequencedTaskRunner* sequenced_task_runner);
|
||||||
|
|
||||||
// PrefStore overrides:
|
// PrefStore overrides:
|
||||||
virtual ReadResult GetValue(const std::string& key,
|
virtual ReadResult GetValue(const std::string& key,
|
||||||
@@ -72,7 +79,7 @@ class BASE_PREFS_EXPORT JsonPrefStore
|
|||||||
virtual bool SerializeData(std::string* output) OVERRIDE;
|
virtual bool SerializeData(std::string* output) OVERRIDE;
|
||||||
|
|
||||||
FilePath path_;
|
FilePath path_;
|
||||||
scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_;
|
const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
|
||||||
|
|
||||||
scoped_ptr<base::DictionaryValue> prefs_;
|
scoped_ptr<base::DictionaryValue> prefs_;
|
||||||
|
|
||||||
|
@@ -5,13 +5,12 @@
|
|||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "base/message_loop.h"
|
|
||||||
#include "base/message_loop_proxy.h"
|
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/prefs/json_pref_store.h"
|
#include "base/prefs/json_pref_store.h"
|
||||||
#include "base/scoped_temp_dir.h"
|
#include "base/scoped_temp_dir.h"
|
||||||
#include "base/string_number_conversions.h"
|
#include "base/string_number_conversions.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "base/threading/thread.h"
|
#include "base/threading/thread.h"
|
||||||
#include "base/utf_string_conversions.h"
|
#include "base/utf_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
@@ -37,9 +36,7 @@ class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
|
|||||||
|
|
||||||
class JsonPrefStoreTest : public testing::Test {
|
class JsonPrefStoreTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() OVERRIDE {
|
||||||
message_loop_proxy_ = base::MessageLoopProxy::current();
|
|
||||||
|
|
||||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||||
|
|
||||||
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_));
|
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_));
|
||||||
@@ -53,7 +50,6 @@ class JsonPrefStoreTest : public testing::Test {
|
|||||||
FilePath data_dir_;
|
FilePath data_dir_;
|
||||||
// A message loop that we can use as the file thread message loop.
|
// A message loop that we can use as the file thread message loop.
|
||||||
MessageLoop message_loop_;
|
MessageLoop message_loop_;
|
||||||
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test fallback behavior for a nonexistent file.
|
// Test fallback behavior for a nonexistent file.
|
||||||
@@ -61,7 +57,8 @@ TEST_F(JsonPrefStoreTest, NonExistentFile) {
|
|||||||
FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
|
FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
|
||||||
ASSERT_FALSE(file_util::PathExists(bogus_input_file));
|
ASSERT_FALSE(file_util::PathExists(bogus_input_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(bogus_input_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
bogus_input_file, message_loop_.message_loop_proxy());
|
||||||
EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
|
EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
|
||||||
pref_store->ReadPrefs());
|
pref_store->ReadPrefs());
|
||||||
EXPECT_FALSE(pref_store->ReadOnly());
|
EXPECT_FALSE(pref_store->ReadOnly());
|
||||||
@@ -73,7 +70,8 @@ TEST_F(JsonPrefStoreTest, InvalidFile) {
|
|||||||
FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json");
|
FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json");
|
||||||
ASSERT_TRUE(file_util::CopyFile(invalid_file_original, invalid_file));
|
ASSERT_TRUE(file_util::CopyFile(invalid_file_original, invalid_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(invalid_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
invalid_file, message_loop_.message_loop_proxy());
|
||||||
EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
|
EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
|
||||||
pref_store->ReadPrefs());
|
pref_store->ReadPrefs());
|
||||||
EXPECT_FALSE(pref_store->ReadOnly());
|
EXPECT_FALSE(pref_store->ReadOnly());
|
||||||
@@ -88,7 +86,7 @@ TEST_F(JsonPrefStoreTest, InvalidFile) {
|
|||||||
|
|
||||||
// This function is used to avoid code duplication while testing synchronous and
|
// This function is used to avoid code duplication while testing synchronous and
|
||||||
// asynchronous version of the JsonPrefStore loading.
|
// asynchronous version of the JsonPrefStore loading.
|
||||||
void RunBasicJsonPrefStoreTest(JsonPrefStore *pref_store,
|
void RunBasicJsonPrefStoreTest(JsonPrefStore* pref_store,
|
||||||
const FilePath& output_file,
|
const FilePath& output_file,
|
||||||
const FilePath& golden_output_file) {
|
const FilePath& golden_output_file) {
|
||||||
const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
|
const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
|
||||||
@@ -166,7 +164,8 @@ TEST_F(JsonPrefStoreTest, Basic) {
|
|||||||
FilePath input_file = temp_dir_.path().AppendASCII("write.json");
|
FilePath input_file = temp_dir_.path().AppendASCII("write.json");
|
||||||
ASSERT_TRUE(file_util::PathExists(input_file));
|
ASSERT_TRUE(file_util::PathExists(input_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(input_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
input_file, message_loop_.message_loop_proxy());
|
||||||
ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
|
ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
|
||||||
ASSERT_FALSE(pref_store->ReadOnly());
|
ASSERT_FALSE(pref_store->ReadOnly());
|
||||||
|
|
||||||
@@ -193,21 +192,24 @@ TEST_F(JsonPrefStoreTest, BasicAsync) {
|
|||||||
FilePath input_file = temp_dir_.path().AppendASCII("write.json");
|
FilePath input_file = temp_dir_.path().AppendASCII("write.json");
|
||||||
ASSERT_TRUE(file_util::PathExists(input_file));
|
ASSERT_TRUE(file_util::PathExists(input_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(input_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
input_file, message_loop_.message_loop_proxy());
|
||||||
|
|
||||||
MockPrefStoreObserver mock_observer;
|
{
|
||||||
pref_store->AddObserver(&mock_observer);
|
MockPrefStoreObserver mock_observer;
|
||||||
|
pref_store->AddObserver(&mock_observer);
|
||||||
|
|
||||||
MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
|
MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
|
||||||
pref_store->ReadPrefsAsync(mock_error_delegate);
|
pref_store->ReadPrefsAsync(mock_error_delegate);
|
||||||
|
|
||||||
EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
|
EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
|
||||||
EXPECT_CALL(*mock_error_delegate,
|
EXPECT_CALL(*mock_error_delegate,
|
||||||
OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
|
OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
|
||||||
message_loop_.RunUntilIdle();
|
message_loop_.RunUntilIdle();
|
||||||
pref_store->RemoveObserver(&mock_observer);
|
pref_store->RemoveObserver(&mock_observer);
|
||||||
|
|
||||||
ASSERT_FALSE(pref_store->ReadOnly());
|
ASSERT_FALSE(pref_store->ReadOnly());
|
||||||
|
}
|
||||||
|
|
||||||
// The JSON file looks like this:
|
// The JSON file looks like this:
|
||||||
// {
|
// {
|
||||||
@@ -229,7 +231,8 @@ TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
|
|||||||
FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
|
FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
|
||||||
ASSERT_FALSE(file_util::PathExists(bogus_input_file));
|
ASSERT_FALSE(file_util::PathExists(bogus_input_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(bogus_input_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
bogus_input_file, message_loop_.message_loop_proxy());
|
||||||
MockPrefStoreObserver mock_observer;
|
MockPrefStoreObserver mock_observer;
|
||||||
pref_store->AddObserver(&mock_observer);
|
pref_store->AddObserver(&mock_observer);
|
||||||
|
|
||||||
@@ -255,7 +258,8 @@ TEST_F(JsonPrefStoreTest, NeedsEmptyValue) {
|
|||||||
// Test that the persistent value can be loaded.
|
// Test that the persistent value can be loaded.
|
||||||
ASSERT_TRUE(file_util::PathExists(pref_file));
|
ASSERT_TRUE(file_util::PathExists(pref_file));
|
||||||
scoped_refptr<JsonPrefStore> pref_store =
|
scoped_refptr<JsonPrefStore> pref_store =
|
||||||
new JsonPrefStore(pref_file, message_loop_proxy_.get());
|
new JsonPrefStore(
|
||||||
|
pref_file, message_loop_.message_loop_proxy());
|
||||||
ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
|
ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
|
||||||
ASSERT_FALSE(pref_store->ReadOnly());
|
ASSERT_FALSE(pref_store->ReadOnly());
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/process.h"
|
#include "base/process.h"
|
||||||
#include "base/process_util.h"
|
#include "base/process_util.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "base/stringprintf.h"
|
#include "base/stringprintf.h"
|
||||||
#include "base/threading/thread_restrictions.h"
|
#include "base/threading/thread_restrictions.h"
|
||||||
#include "base/time.h"
|
#include "base/time.h"
|
||||||
@@ -1288,7 +1289,9 @@ void TestingAutomationProvider::GetBookmarksAsJSON(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scoped_refptr<BookmarkStorage> storage(
|
scoped_refptr<BookmarkStorage> storage(
|
||||||
new BookmarkStorage(browser->profile(), bookmark_model));
|
new BookmarkStorage(browser->profile(),
|
||||||
|
bookmark_model,
|
||||||
|
browser->profile()->GetIOTaskRunner()));
|
||||||
if (!storage->SerializeData(&bookmarks_as_json)) {
|
if (!storage->SerializeData(&bookmarks_as_json)) {
|
||||||
reply.SendError("Failed to serialize bookmarks");
|
reply.SendError("Failed to serialize bookmarks");
|
||||||
return;
|
return;
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "base/bind_helpers.h"
|
#include "base/bind_helpers.h"
|
||||||
#include "base/json/json_string_value_serializer.h"
|
#include "base/json/json_string_value_serializer.h"
|
||||||
#include "base/memory/scoped_vector.h"
|
#include "base/memory/scoped_vector.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
@@ -247,7 +248,7 @@ void BookmarkModel::Load() {
|
|||||||
content::Source<Profile>(profile_));
|
content::Source<Profile>(profile_));
|
||||||
|
|
||||||
// Load the bookmarks. BookmarkStorage notifies us when done.
|
// Load the bookmarks. BookmarkStorage notifies us when done.
|
||||||
store_ = new BookmarkStorage(profile_, this);
|
store_ = new BookmarkStorage(profile_, this, profile_->GetIOTaskRunner());
|
||||||
store_->LoadBookmarks(CreateLoadDetails());
|
store_->LoadBookmarks(CreateLoadDetails());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -107,15 +107,17 @@ BookmarkLoadDetails::~BookmarkLoadDetails() {
|
|||||||
|
|
||||||
// BookmarkStorage -------------------------------------------------------------
|
// BookmarkStorage -------------------------------------------------------------
|
||||||
|
|
||||||
BookmarkStorage::BookmarkStorage(content::BrowserContext* context,
|
BookmarkStorage::BookmarkStorage(
|
||||||
BookmarkModel* model)
|
content::BrowserContext* context,
|
||||||
|
BookmarkModel* model,
|
||||||
|
base::SequencedTaskRunner* sequenced_task_runner)
|
||||||
: model_(model),
|
: model_(model),
|
||||||
writer_(context->GetPath().Append(chrome::kBookmarksFileName),
|
writer_(context->GetPath().Append(chrome::kBookmarksFileName),
|
||||||
BrowserThread::GetMessageLoopProxyForThread(
|
sequenced_task_runner) {
|
||||||
BrowserThread::FILE)) {
|
sequenced_task_runner_ = sequenced_task_runner;
|
||||||
writer_.set_commit_interval(base::TimeDelta::FromMilliseconds(kSaveDelayMS));
|
writer_.set_commit_interval(base::TimeDelta::FromMilliseconds(kSaveDelayMS));
|
||||||
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
|
sequenced_task_runner_->PostTask(FROM_HERE,
|
||||||
base::Bind(&BackupCallback, writer_.path()));
|
base::Bind(&BackupCallback, writer_.path()));
|
||||||
}
|
}
|
||||||
|
|
||||||
BookmarkStorage::~BookmarkStorage() {
|
BookmarkStorage::~BookmarkStorage() {
|
||||||
@@ -127,8 +129,10 @@ void BookmarkStorage::LoadBookmarks(BookmarkLoadDetails* details) {
|
|||||||
DCHECK(!details_.get());
|
DCHECK(!details_.get());
|
||||||
DCHECK(details);
|
DCHECK(details);
|
||||||
details_.reset(details);
|
details_.reset(details);
|
||||||
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
|
sequenced_task_runner_->PostTask(
|
||||||
&LoadCallback, writer_.path(), make_scoped_refptr(this), details_.get()));
|
FROM_HERE,
|
||||||
|
base::Bind(&LoadCallback, writer_.path(), make_scoped_refptr(this),
|
||||||
|
details_.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BookmarkStorage::ScheduleSave() {
|
void BookmarkStorage::ScheduleSave() {
|
||||||
|
@@ -13,6 +13,10 @@
|
|||||||
class BookmarkModel;
|
class BookmarkModel;
|
||||||
class BookmarkPermanentNode;
|
class BookmarkPermanentNode;
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
|
}
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class BrowserContext;
|
class BrowserContext;
|
||||||
}
|
}
|
||||||
@@ -102,7 +106,9 @@ class BookmarkStorage : public base::ImportantFileWriter::DataSerializer,
|
|||||||
public base::RefCountedThreadSafe<BookmarkStorage> {
|
public base::RefCountedThreadSafe<BookmarkStorage> {
|
||||||
public:
|
public:
|
||||||
// Creates a BookmarkStorage for the specified model
|
// Creates a BookmarkStorage for the specified model
|
||||||
BookmarkStorage(content::BrowserContext* context, BookmarkModel* model);
|
BookmarkStorage(content::BrowserContext* context,
|
||||||
|
BookmarkModel* model,
|
||||||
|
base::SequencedTaskRunner* sequenced_task_runner);
|
||||||
|
|
||||||
// Loads the bookmarks into the model, notifying the model when done. This
|
// Loads the bookmarks into the model, notifying the model when done. This
|
||||||
// takes ownership of |details|. See BookmarkLoadDetails for details.
|
// takes ownership of |details|. See BookmarkLoadDetails for details.
|
||||||
@@ -139,6 +145,9 @@ class BookmarkStorage : public base::ImportantFileWriter::DataSerializer,
|
|||||||
// See class description of BookmarkLoadDetails for details on this.
|
// See class description of BookmarkLoadDetails for details on this.
|
||||||
scoped_ptr<BookmarkLoadDetails> details_;
|
scoped_ptr<BookmarkLoadDetails> details_;
|
||||||
|
|
||||||
|
// Sequenced task runner where file I/O operations will be performed at.
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BookmarkStorage);
|
DISALLOW_COPY_AND_ASSIGN(BookmarkStorage);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -133,7 +133,9 @@ using content::ChildProcessSecurityPolicy;
|
|||||||
using content::PluginService;
|
using content::PluginService;
|
||||||
using content::ResourceDispatcherHost;
|
using content::ResourceDispatcherHost;
|
||||||
|
|
||||||
BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line)
|
BrowserProcessImpl::BrowserProcessImpl(
|
||||||
|
base::SequencedTaskRunner* local_state_task_runner,
|
||||||
|
const CommandLine& command_line)
|
||||||
: created_metrics_service_(false),
|
: created_metrics_service_(false),
|
||||||
created_watchdog_thread_(false),
|
created_watchdog_thread_(false),
|
||||||
created_browser_policy_connector_(false),
|
created_browser_policy_connector_(false),
|
||||||
@@ -147,7 +149,8 @@ BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line)
|
|||||||
checked_for_new_frames_(false),
|
checked_for_new_frames_(false),
|
||||||
using_new_frames_(false),
|
using_new_frames_(false),
|
||||||
render_widget_snapshot_taker_(new RenderWidgetSnapshotTaker),
|
render_widget_snapshot_taker_(new RenderWidgetSnapshotTaker),
|
||||||
download_status_updater_(new DownloadStatusUpdater) {
|
download_status_updater_(new DownloadStatusUpdater),
|
||||||
|
local_state_task_runner_(local_state_task_runner) {
|
||||||
g_browser_process = this;
|
g_browser_process = this;
|
||||||
|
|
||||||
#if defined(ENABLE_PRINTING)
|
#if defined(ENABLE_PRINTING)
|
||||||
@@ -709,10 +712,10 @@ void BrowserProcessImpl::CreateLocalState() {
|
|||||||
created_local_state_ = true;
|
created_local_state_ = true;
|
||||||
|
|
||||||
FilePath local_state_path;
|
FilePath local_state_path;
|
||||||
PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
|
CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path));
|
||||||
local_state_.reset(
|
local_state_.reset(
|
||||||
PrefService::CreatePrefService(local_state_path, policy_service(), NULL,
|
PrefService::CreatePrefService(local_state_path, local_state_task_runner_,
|
||||||
false));
|
policy_service(), NULL, false));
|
||||||
|
|
||||||
// Initialize the prefs of the local state.
|
// Initialize the prefs of the local state.
|
||||||
chrome::RegisterLocalState(local_state_.get());
|
chrome::RegisterLocalState(local_state_.get());
|
||||||
|
@@ -31,6 +31,10 @@ class RemoteDebuggingServer;
|
|||||||
class PluginsResourceService;
|
class PluginsResourceService;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
|
}
|
||||||
|
|
||||||
namespace policy {
|
namespace policy {
|
||||||
class BrowserPolicyConnector;
|
class BrowserPolicyConnector;
|
||||||
class PolicyService;
|
class PolicyService;
|
||||||
@@ -41,7 +45,9 @@ class BrowserProcessImpl : public BrowserProcess,
|
|||||||
public base::NonThreadSafe,
|
public base::NonThreadSafe,
|
||||||
public PrefObserver {
|
public PrefObserver {
|
||||||
public:
|
public:
|
||||||
explicit BrowserProcessImpl(const CommandLine& command_line);
|
// |local_state_task_runner| must be a shutdown-blocking task runner.
|
||||||
|
BrowserProcessImpl(base::SequencedTaskRunner* local_state_task_runner,
|
||||||
|
const CommandLine& command_line);
|
||||||
virtual ~BrowserProcessImpl();
|
virtual ~BrowserProcessImpl();
|
||||||
|
|
||||||
// Called before the browser threads are created.
|
// Called before the browser threads are created.
|
||||||
@@ -226,6 +232,9 @@ class BrowserProcessImpl : public BrowserProcess,
|
|||||||
|
|
||||||
scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
|
scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
|
||||||
|
|
||||||
|
// Sequenced task runner for local state related I/O tasks.
|
||||||
|
const scoped_refptr<base::SequencedTaskRunner> local_state_task_runner_;
|
||||||
|
|
||||||
// Ensures that the observers of plugin/print disable/enable state
|
// Ensures that the observers of plugin/print disable/enable state
|
||||||
// notifications are properly added and removed.
|
// notifications are properly added and removed.
|
||||||
PrefChangeRegistrar pref_change_registrar_;
|
PrefChangeRegistrar pref_change_registrar_;
|
||||||
|
@@ -277,8 +277,11 @@ void InitializeNetworkOptions(const CommandLine& parsed_command_line,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the new local state object, guaranteed non-NULL.
|
// Returns the new local state object, guaranteed non-NULL.
|
||||||
PrefService* InitializeLocalState(const CommandLine& parsed_command_line,
|
// |local_state_task_runner| must be a shutdown-blocking task runner.
|
||||||
bool is_first_run) {
|
PrefService* InitializeLocalState(
|
||||||
|
base::SequencedTaskRunner* local_state_task_runner,
|
||||||
|
const CommandLine& parsed_command_line,
|
||||||
|
bool is_first_run) {
|
||||||
FilePath local_state_path;
|
FilePath local_state_path;
|
||||||
PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
|
PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
|
||||||
bool local_state_file_exists = file_util::PathExists(local_state_path);
|
bool local_state_file_exists = file_util::PathExists(local_state_path);
|
||||||
@@ -332,7 +335,7 @@ PrefService* InitializeLocalState(const CommandLine& parsed_command_line,
|
|||||||
FilePath parent_profile =
|
FilePath parent_profile =
|
||||||
parsed_command_line.GetSwitchValuePath(switches::kParentProfile);
|
parsed_command_line.GetSwitchValuePath(switches::kParentProfile);
|
||||||
scoped_ptr<PrefService> parent_local_state(
|
scoped_ptr<PrefService> parent_local_state(
|
||||||
PrefService::CreatePrefService(parent_profile,
|
PrefService::CreatePrefService(parent_profile, local_state_task_runner,
|
||||||
g_browser_process->policy_service(),
|
g_browser_process->policy_service(),
|
||||||
NULL, false));
|
NULL, false));
|
||||||
parent_local_state->RegisterStringPref(prefs::kApplicationLocale,
|
parent_local_state->RegisterStringPref(prefs::kApplicationLocale,
|
||||||
@@ -723,7 +726,14 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
|
|||||||
parsed_command_line().HasSwitch(switches::kFirstRun)) &&
|
parsed_command_line().HasSwitch(switches::kFirstRun)) &&
|
||||||
!HasImportSwitch(parsed_command_line());
|
!HasImportSwitch(parsed_command_line());
|
||||||
#endif
|
#endif
|
||||||
browser_process_.reset(new BrowserProcessImpl(parsed_command_line()));
|
|
||||||
|
FilePath local_state_path;
|
||||||
|
CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path));
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> local_state_task_runner =
|
||||||
|
JsonPrefStore::GetTaskRunnerForFile(local_state_path,
|
||||||
|
BrowserThread::GetBlockingPool());
|
||||||
|
browser_process_.reset(new BrowserProcessImpl(local_state_task_runner,
|
||||||
|
parsed_command_line()));
|
||||||
|
|
||||||
if (parsed_command_line().HasSwitch(switches::kEnableProfiling)) {
|
if (parsed_command_line().HasSwitch(switches::kEnableProfiling)) {
|
||||||
// User wants to override default tracking status.
|
// User wants to override default tracking status.
|
||||||
@@ -745,7 +755,9 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
|
|||||||
switches::kProfilingOutputFile));
|
switches::kProfilingOutputFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
local_state_ = InitializeLocalState(parsed_command_line(), is_first_run_);
|
local_state_ = InitializeLocalState(local_state_task_runner,
|
||||||
|
parsed_command_line(),
|
||||||
|
is_first_run_);
|
||||||
|
|
||||||
// These members must be initialized before returning from this function.
|
// These members must be initialized before returning from this function.
|
||||||
master_prefs_.reset(new first_run::MasterPrefs);
|
master_prefs_.reset(new first_run::MasterPrefs);
|
||||||
|
@@ -220,14 +220,14 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
connector_ = browser_process_->browser_policy_connector();
|
connector_ = browser_process_->browser_policy_connector();
|
||||||
connector_->Init();
|
connector_->Init();
|
||||||
|
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() OVERRIDE {
|
virtual void TearDown() OVERRIDE {
|
||||||
cryptohome::AsyncMethodCaller::Shutdown();
|
cryptohome::AsyncMethodCaller::Shutdown();
|
||||||
mock_async_method_caller_ = NULL;
|
mock_async_method_caller_ = NULL;
|
||||||
|
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
{
|
{
|
||||||
// chrome_browser_net::Predictor usually skips its shutdown routines on
|
// chrome_browser_net::Predictor usually skips its shutdown routines on
|
||||||
// unit_tests, but does the full thing when
|
// unit_tests, but does the full thing when
|
||||||
@@ -242,7 +242,7 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
loop_.PostTask(FROM_HERE,
|
loop_.PostTask(FROM_HERE,
|
||||||
base::Bind(&LoginUtilsTest::TearDownOnIO,
|
base::Bind(&LoginUtilsTest::TearDownOnIO,
|
||||||
base::Unretained(this)));
|
base::Unretained(this)));
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
io_thread_.DeprecatedSetMessageLoop(NULL);
|
io_thread_.DeprecatedSetMessageLoop(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
browser_process_->SetProfileManager(NULL);
|
browser_process_->SetProfileManager(NULL);
|
||||||
connector_ = NULL;
|
connector_ = NULL;
|
||||||
browser_process_->SetBrowserPolicyConnector(NULL);
|
browser_process_->SetBrowserPolicyConnector(NULL);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDownOnIO() {
|
void TearDownOnIO() {
|
||||||
@@ -267,10 +267,10 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunAllPending() {
|
void RunUntilIdle() {
|
||||||
loop_.RunAllPending();
|
loop_.RunUntilIdle();
|
||||||
BrowserThread::GetBlockingPool()->FlushForTesting();
|
BrowserThread::GetBlockingPool()->FlushForTesting();
|
||||||
loop_.RunAllPending();
|
loop_.RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
|
virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
|
||||||
@@ -299,7 +299,7 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
device_data_store->set_device_id(kDeviceId);
|
device_data_store->set_device_id(kDeviceId);
|
||||||
EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS,
|
EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS,
|
||||||
connector_->LockDevice(username));
|
connector_->LockDevice(username));
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareProfile(const std::string& username) {
|
void PrepareProfile(const std::string& username) {
|
||||||
@@ -325,7 +325,7 @@ class LoginUtilsTest : public testing::Test,
|
|||||||
kPendingRequests, kUsingOAuth,
|
kPendingRequests, kUsingOAuth,
|
||||||
kHasCookies, this);
|
kHasCookies, this);
|
||||||
device_settings_test_helper.Flush();
|
device_settings_test_helper.Flush();
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
net::TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) {
|
net::TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) {
|
||||||
@@ -477,7 +477,7 @@ TEST_F(LoginUtilsTest, OAuth1TokenFetchFailureUnblocksRefreshPolicies) {
|
|||||||
bool refresh_policies_completed = false;
|
bool refresh_policies_completed = false;
|
||||||
browser_process_->policy_service()->RefreshPolicies(
|
browser_process_->policy_service()->RefreshPolicies(
|
||||||
base::Bind(SetFlag, &refresh_policies_completed));
|
base::Bind(SetFlag, &refresh_policies_completed));
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
ASSERT_FALSE(refresh_policies_completed);
|
ASSERT_FALSE(refresh_policies_completed);
|
||||||
|
|
||||||
// 4. Now make the fetcher fail. RefreshPolicies() should unblock.
|
// 4. Now make the fetcher fail. RefreshPolicies() should unblock.
|
||||||
@@ -495,7 +495,7 @@ TEST_F(LoginUtilsTest, OAuth1TokenFetchFailureUnblocksRefreshPolicies) {
|
|||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
ASSERT_FALSE(refresh_policies_completed);
|
ASSERT_FALSE(refresh_policies_completed);
|
||||||
delegate->OnURLFetchComplete(&mock_fetcher);
|
delegate->OnURLFetchComplete(&mock_fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
EXPECT_TRUE(refresh_policies_completed);
|
EXPECT_TRUE(refresh_policies_completed);
|
||||||
}
|
}
|
||||||
@@ -555,14 +555,14 @@ TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) {
|
|||||||
|
|
||||||
// The cloud policy subsystem is now ready to fetch the dmtoken and the user
|
// The cloud policy subsystem is now ready to fetch the dmtoken and the user
|
||||||
// policy.
|
// policy.
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
if (steps < 4) break;
|
if (steps < 4) break;
|
||||||
|
|
||||||
fetcher = PrepareDMRegisterFetcher();
|
fetcher = PrepareDMRegisterFetcher();
|
||||||
ASSERT_TRUE(fetcher);
|
ASSERT_TRUE(fetcher);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
// The policy fetch job has now been scheduled, run it:
|
// The policy fetch job has now been scheduled, run it:
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
if (steps < 5) break;
|
if (steps < 5) break;
|
||||||
|
|
||||||
// Verify that there is no profile prepared just before the policy fetch.
|
// Verify that there is no profile prepared just before the policy fetch.
|
||||||
|
@@ -53,10 +53,11 @@ static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
|
|||||||
|
|
||||||
ExtensionPrefsTest::ExtensionPrefsTest()
|
ExtensionPrefsTest::ExtensionPrefsTest()
|
||||||
: ui_thread_(BrowserThread::UI, &message_loop_),
|
: ui_thread_(BrowserThread::UI, &message_loop_),
|
||||||
file_thread_(BrowserThread::FILE, &message_loop_) {
|
prefs_(message_loop_.message_loop_proxy()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtensionPrefsTest::~ExtensionPrefsTest() {}
|
ExtensionPrefsTest::~ExtensionPrefsTest() {
|
||||||
|
}
|
||||||
|
|
||||||
void ExtensionPrefsTest::RegisterPreferences() {}
|
void ExtensionPrefsTest::RegisterPreferences() {}
|
||||||
|
|
||||||
@@ -72,6 +73,8 @@ void ExtensionPrefsTest::TearDown() {
|
|||||||
prefs_.RecreateExtensionPrefs();
|
prefs_.RecreateExtensionPrefs();
|
||||||
RegisterPreferences();
|
RegisterPreferences();
|
||||||
Verify();
|
Verify();
|
||||||
|
prefs_.pref_service()->CommitPendingWrite();
|
||||||
|
message_loop_.RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the LastPingDay/SetLastPingDay functions.
|
// Tests the LastPingDay/SetLastPingDay functions.
|
||||||
|
@@ -44,7 +44,6 @@ class ExtensionPrefsTest : public testing::Test {
|
|||||||
|
|
||||||
MessageLoop message_loop_;
|
MessageLoop message_loop_;
|
||||||
content::TestBrowserThread ui_thread_;
|
content::TestBrowserThread ui_thread_;
|
||||||
content::TestBrowserThread file_thread_;
|
|
||||||
|
|
||||||
TestExtensionPrefs prefs_;
|
TestExtensionPrefs prefs_;
|
||||||
|
|
||||||
|
@@ -422,7 +422,8 @@ void ExtensionServiceTestBase::InitializeExtensionService(
|
|||||||
TestingProfile::Builder profile_builder;
|
TestingProfile::Builder profile_builder;
|
||||||
// Create a PrefService that only contains user defined preference values.
|
// Create a PrefService that only contains user defined preference values.
|
||||||
scoped_ptr<PrefService> prefs(
|
scoped_ptr<PrefService> prefs(
|
||||||
PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create());
|
PrefServiceMockBuilder().WithUserFilePrefs(
|
||||||
|
pref_file, loop_.message_loop_proxy()).Create());
|
||||||
Profile::RegisterUserPrefs(prefs.get());
|
Profile::RegisterUserPrefs(prefs.get());
|
||||||
chrome::RegisterUserPrefs(prefs.get());
|
chrome::RegisterUserPrefs(prefs.get());
|
||||||
profile_builder.SetPrefService(prefs.Pass());
|
profile_builder.SetPrefService(prefs.Pass());
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "chrome/browser/extensions/event_router.h"
|
#include "chrome/browser/extensions/event_router.h"
|
||||||
#include "chrome/browser/extensions/extension_system_factory.h"
|
#include "chrome/browser/extensions/extension_system_factory.h"
|
||||||
#include "chrome/browser/extensions/menu_manager.h"
|
#include "chrome/browser/extensions/menu_manager.h"
|
||||||
|
#include "chrome/browser/prefs/pref_service.h"
|
||||||
#include "chrome/browser/extensions/test_extension_prefs.h"
|
#include "chrome/browser/extensions/test_extension_prefs.h"
|
||||||
#include "chrome/browser/extensions/test_extension_system.h"
|
#include "chrome/browser/extensions/test_extension_system.h"
|
||||||
#include "chrome/common/chrome_notification_types.h"
|
#include "chrome/common/chrome_notification_types.h"
|
||||||
@@ -44,9 +45,15 @@ class MenuManagerTest : public testing::Test {
|
|||||||
MenuManagerTest() : ui_thread_(BrowserThread::UI, &message_loop_),
|
MenuManagerTest() : ui_thread_(BrowserThread::UI, &message_loop_),
|
||||||
file_thread_(BrowserThread::FILE, &message_loop_),
|
file_thread_(BrowserThread::FILE, &message_loop_),
|
||||||
manager_(&profile_),
|
manager_(&profile_),
|
||||||
|
prefs_(message_loop_.message_loop_proxy()),
|
||||||
next_id_(1) {
|
next_id_(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() OVERRIDE {
|
||||||
|
prefs_.pref_service()->CommitPendingWrite();
|
||||||
|
message_loop_.RunUntilIdle();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a test item.
|
// Returns a test item.
|
||||||
MenuItem* CreateTestItem(Extension* extension, bool incognito = false) {
|
MenuItem* CreateTestItem(Extension* extension, bool incognito = false) {
|
||||||
MenuItem::Type type = MenuItem::NORMAL;
|
MenuItem::Type type = MenuItem::NORMAL;
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
#include "base/message_loop.h"
|
#include "base/message_loop.h"
|
||||||
#include "base/message_loop_proxy.h"
|
#include "base/message_loop_proxy.h"
|
||||||
#include "base/prefs/json_pref_store.h"
|
#include "base/prefs/json_pref_store.h"
|
||||||
|
#include "base/run_loop.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "chrome/browser/extensions/extension_pref_store.h"
|
#include "chrome/browser/extensions/extension_pref_store.h"
|
||||||
@@ -31,6 +33,8 @@ namespace extensions {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void DoNothing() {}
|
||||||
|
|
||||||
// Mock ExtensionPrefs class with artificial clock to guarantee that no two
|
// Mock ExtensionPrefs class with artificial clock to guarantee that no two
|
||||||
// extensions get the same installation time stamp and we can reliably
|
// extensions get the same installation time stamp and we can reliably
|
||||||
// assert the installation order in the tests below.
|
// assert the installation order in the tests below.
|
||||||
@@ -54,9 +58,10 @@ class MockExtensionPrefs : public ExtensionPrefs {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TestExtensionPrefs::TestExtensionPrefs()
|
TestExtensionPrefs::TestExtensionPrefs(
|
||||||
: pref_service_(NULL),
|
base::SequencedTaskRunner* task_runner) : pref_service_(NULL),
|
||||||
extensions_disabled_(false) {
|
task_runner_(task_runner),
|
||||||
|
extensions_disabled_(false) {
|
||||||
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
|
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||||
preferences_file_ = temp_dir_.path().AppendASCII("Preferences");
|
preferences_file_ = temp_dir_.path().AppendASCII("Preferences");
|
||||||
extensions_dir_ = temp_dir_.path().AppendASCII("Extensions");
|
extensions_dir_ = temp_dir_.path().AppendASCII("Extensions");
|
||||||
@@ -65,36 +70,29 @@ TestExtensionPrefs::TestExtensionPrefs()
|
|||||||
RecreateExtensionPrefs();
|
RecreateExtensionPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
TestExtensionPrefs::~TestExtensionPrefs() {}
|
TestExtensionPrefs::~TestExtensionPrefs() {
|
||||||
|
}
|
||||||
|
|
||||||
void TestExtensionPrefs::RecreateExtensionPrefs() {
|
void TestExtensionPrefs::RecreateExtensionPrefs() {
|
||||||
// We persist and reload the PrefService's PrefStores because this process
|
// We persist and reload the PrefService's PrefStores because this process
|
||||||
// deletes all empty dictionaries. The ExtensionPrefs implementation
|
// deletes all empty dictionaries. The ExtensionPrefs implementation
|
||||||
// needs to be able to handle this situation.
|
// needs to be able to handle this situation.
|
||||||
if (pref_service_.get()) {
|
if (pref_service_.get()) {
|
||||||
// The PrefService writes its persistent file on the file thread, so we
|
// Commit a pending write (which posts a task to task_runner_) and wait for
|
||||||
// need to wait for any pending I/O to complete before creating a new
|
// it to finish.
|
||||||
// PrefService.
|
pref_service_->CommitPendingWrite();
|
||||||
base::WaitableEvent io_finished(false, false);
|
base::RunLoop run_loop;
|
||||||
pref_service_-> CommitPendingWrite();
|
ASSERT_TRUE(
|
||||||
EXPECT_TRUE(BrowserThread::PostTask(
|
task_runner_->PostTaskAndReply(
|
||||||
BrowserThread::FILE,
|
FROM_HERE,
|
||||||
FROM_HERE,
|
base::Bind(&DoNothing),
|
||||||
base::Bind(&base::WaitableEvent::Signal,
|
run_loop.QuitClosure()));
|
||||||
base::Unretained(&io_finished))));
|
run_loop.Run();
|
||||||
|
|
||||||
// If the FILE thread is in fact the current thread (possible in testing
|
|
||||||
// scenarios), we have to ensure the task has a chance to run. If the FILE
|
|
||||||
// thread is a different thread, the test must ensure that thread is running
|
|
||||||
// (otherwise the Wait below will hang).
|
|
||||||
MessageLoop::current()->RunAllPending();
|
|
||||||
|
|
||||||
io_finished.Wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension_pref_value_map_.reset(new ExtensionPrefValueMap);
|
extension_pref_value_map_.reset(new ExtensionPrefValueMap);
|
||||||
PrefServiceMockBuilder builder;
|
PrefServiceMockBuilder builder;
|
||||||
builder.WithUserFilePrefs(preferences_file_);
|
builder.WithUserFilePrefs(preferences_file_, task_runner_);
|
||||||
builder.WithExtensionPrefs(
|
builder.WithExtensionPrefs(
|
||||||
new ExtensionPrefStore(extension_pref_value_map_.get(), false));
|
new ExtensionPrefStore(extension_pref_value_map_.get(), false));
|
||||||
pref_service_.reset(builder.Create());
|
pref_service_.reset(builder.Create());
|
||||||
|
@@ -16,6 +16,7 @@ class PrefService;
|
|||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class DictionaryValue;
|
class DictionaryValue;
|
||||||
|
class SequencedTaskRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace extensions {
|
namespace extensions {
|
||||||
@@ -25,7 +26,7 @@ class ExtensionPrefs;
|
|||||||
// in tests.
|
// in tests.
|
||||||
class TestExtensionPrefs {
|
class TestExtensionPrefs {
|
||||||
public:
|
public:
|
||||||
TestExtensionPrefs();
|
explicit TestExtensionPrefs(base::SequencedTaskRunner* task_runner);
|
||||||
virtual ~TestExtensionPrefs();
|
virtual ~TestExtensionPrefs();
|
||||||
|
|
||||||
ExtensionPrefs* prefs() { return prefs_.get(); }
|
ExtensionPrefs* prefs() { return prefs_.get(); }
|
||||||
@@ -77,6 +78,7 @@ class TestExtensionPrefs {
|
|||||||
scoped_ptr<PrefService> pref_service_;
|
scoped_ptr<PrefService> pref_service_;
|
||||||
scoped_ptr<ExtensionPrefs> prefs_;
|
scoped_ptr<ExtensionPrefs> prefs_;
|
||||||
scoped_ptr<ExtensionPrefValueMap> extension_pref_value_map_;
|
scoped_ptr<ExtensionPrefValueMap> extension_pref_value_map_;
|
||||||
|
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool extensions_disabled_;
|
bool extensions_disabled_;
|
||||||
|
@@ -162,10 +162,12 @@ class NotificationsObserver : public content::NotificationObserver {
|
|||||||
// Base class for further specialized test classes.
|
// Base class for further specialized test classes.
|
||||||
class MockService : public TestExtensionService {
|
class MockService : public TestExtensionService {
|
||||||
public:
|
public:
|
||||||
MockService()
|
explicit MockService(TestExtensionPrefs* prefs)
|
||||||
: pending_extension_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(*this)) {
|
: prefs_(prefs),
|
||||||
|
pending_extension_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(*this)) {
|
||||||
profile_.CreateRequestContext();
|
profile_.CreateRequestContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~MockService() {}
|
virtual ~MockService() {}
|
||||||
|
|
||||||
virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
|
virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
|
||||||
@@ -180,9 +182,9 @@ class MockService : public TestExtensionService {
|
|||||||
return profile_.GetRequestContext();
|
return profile_.GetRequestContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtensionPrefs* extension_prefs() { return prefs_.prefs(); }
|
ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
|
||||||
|
|
||||||
PrefService* pref_service() { return prefs_.pref_service(); }
|
PrefService* pref_service() { return prefs_->pref_service(); }
|
||||||
|
|
||||||
// Creates test extensions and inserts them into list. The name and
|
// Creates test extensions and inserts them into list. The name and
|
||||||
// version are all based on their index. If |update_url| is non-null, it
|
// version are all based on their index. If |update_url| is non-null, it
|
||||||
@@ -201,15 +203,15 @@ class MockService : public TestExtensionService {
|
|||||||
if (update_url)
|
if (update_url)
|
||||||
manifest.SetString(extension_manifest_keys::kUpdateURL, *update_url);
|
manifest.SetString(extension_manifest_keys::kUpdateURL, *update_url);
|
||||||
scoped_refptr<Extension> e =
|
scoped_refptr<Extension> e =
|
||||||
prefs_.AddExtensionWithManifest(manifest, location);
|
prefs_->AddExtensionWithManifest(manifest, location);
|
||||||
ASSERT_TRUE(e != NULL);
|
ASSERT_TRUE(e != NULL);
|
||||||
list->push_back(e);
|
list->push_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
TestExtensionPrefs* const prefs_;
|
||||||
PendingExtensionManager pending_extension_manager_;
|
PendingExtensionManager pending_extension_manager_;
|
||||||
TestExtensionPrefs prefs_;
|
|
||||||
TestingProfile profile_;
|
TestingProfile profile_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -260,7 +262,9 @@ void SetupPendingExtensionManagerForTest(
|
|||||||
|
|
||||||
class ServiceForManifestTests : public MockService {
|
class ServiceForManifestTests : public MockService {
|
||||||
public:
|
public:
|
||||||
ServiceForManifestTests() {}
|
explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
|
||||||
|
: MockService(prefs) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~ServiceForManifestTests() {}
|
virtual ~ServiceForManifestTests() {}
|
||||||
|
|
||||||
@@ -305,8 +309,8 @@ class ServiceForManifestTests : public MockService {
|
|||||||
|
|
||||||
class ServiceForDownloadTests : public MockService {
|
class ServiceForDownloadTests : public MockService {
|
||||||
public:
|
public:
|
||||||
ServiceForDownloadTests()
|
explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
|
||||||
: MockService() {
|
: MockService(prefs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a fake crx installer to be returned by a call to UpdateExtension()
|
// Add a fake crx installer to be returned by a call to UpdateExtension()
|
||||||
@@ -369,8 +373,8 @@ class ServiceForDownloadTests : public MockService {
|
|||||||
|
|
||||||
class ServiceForBlacklistTests : public MockService {
|
class ServiceForBlacklistTests : public MockService {
|
||||||
public:
|
public:
|
||||||
ServiceForBlacklistTests()
|
explicit ServiceForBlacklistTests(TestExtensionPrefs* prefs)
|
||||||
: MockService(),
|
: MockService(prefs),
|
||||||
processed_blacklist_(false) {
|
processed_blacklist_(false) {
|
||||||
}
|
}
|
||||||
virtual void UpdateExtensionBlacklist(
|
virtual void UpdateExtensionBlacklist(
|
||||||
@@ -417,17 +421,27 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
ExtensionUpdaterTest()
|
ExtensionUpdaterTest()
|
||||||
: ui_thread_(BrowserThread::UI, &loop_),
|
: ui_thread_(BrowserThread::UI, &loop_),
|
||||||
file_thread_(BrowserThread::FILE, &loop_),
|
file_thread_(BrowserThread::FILE, &loop_),
|
||||||
io_thread_(BrowserThread::IO, &loop_) {}
|
io_thread_(BrowserThread::IO, &loop_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ExtensionUpdaterTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void SetUp() OVERRIDE {
|
||||||
|
prefs_.reset(new TestExtensionPrefs(loop_.message_loop_proxy()));
|
||||||
|
}
|
||||||
|
|
||||||
virtual void TearDown() OVERRIDE {
|
virtual void TearDown() OVERRIDE {
|
||||||
// Some tests create URLRequestContextGetters, whose destruction must run
|
// Some tests create URLRequestContextGetters, whose destruction must run
|
||||||
// on the IO thread. Make sure the IO loop spins before shutdown so that
|
// on the IO thread. Make sure the IO loop spins before shutdown so that
|
||||||
// those objects are released.
|
// those objects are released.
|
||||||
loop_.RunAllPending();
|
RunUntilIdle();
|
||||||
|
prefs_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunAllPending() {
|
void RunUntilIdle() {
|
||||||
loop_.RunAllPending();
|
prefs_->pref_service()->CommitPendingWrite();
|
||||||
|
loop_.RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulateTimerFired(ExtensionUpdater* updater) {
|
void SimulateTimerFired(ExtensionUpdater* updater) {
|
||||||
@@ -466,7 +480,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
|
|
||||||
void TestExtensionUpdateCheckRequests(bool pending) {
|
void TestExtensionUpdateCheckRequests(bool pending) {
|
||||||
// Create an extension with an update_url.
|
// Create an extension with an update_url.
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
std::string update_url("http://foo.com/bar");
|
std::string update_url("http://foo.com/bar");
|
||||||
ExtensionList extensions;
|
ExtensionList extensions;
|
||||||
PendingExtensionManager* pending_extension_manager =
|
PendingExtensionManager* pending_extension_manager =
|
||||||
@@ -526,7 +540,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
|
|
||||||
void TestBlacklistUpdateCheckRequests() {
|
void TestBlacklistUpdateCheckRequests() {
|
||||||
// Setup and start the updater.
|
// Setup and start the updater.
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
|
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
ExtensionUpdater updater(
|
ExtensionUpdater updater(
|
||||||
@@ -608,7 +622,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
|
void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
|
|
||||||
MockService service;
|
MockService service(prefs_.get());
|
||||||
MockExtensionDownloaderDelegate delegate;
|
MockExtensionDownloaderDelegate delegate;
|
||||||
ExtensionDownloader downloader(&delegate, service.request_context());
|
ExtensionDownloader downloader(&delegate, service.request_context());
|
||||||
ExtensionList extensions;
|
ExtensionList extensions;
|
||||||
@@ -689,7 +703,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
|
|
||||||
void TestDetermineUpdatesPending() {
|
void TestDetermineUpdatesPending() {
|
||||||
// Create a set of test extensions
|
// Create a set of test extensions
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
PendingExtensionManager* pending_extension_manager =
|
PendingExtensionManager* pending_extension_manager =
|
||||||
service.pending_extension_manager();
|
service.pending_extension_manager();
|
||||||
SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
|
SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
|
||||||
@@ -731,7 +745,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
net::TestURLFetcher* fetcher = NULL;
|
net::TestURLFetcher* fetcher = NULL;
|
||||||
NotificationsObserver observer;
|
NotificationsObserver observer;
|
||||||
MockService service;
|
MockService service(prefs_.get());
|
||||||
MockExtensionDownloaderDelegate delegate;
|
MockExtensionDownloaderDelegate delegate;
|
||||||
ExtensionDownloader downloader(&delegate, service.request_context());
|
ExtensionDownloader downloader(&delegate, service.request_context());
|
||||||
|
|
||||||
@@ -753,7 +767,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
downloader.StartUpdateCheck(fetch2);
|
downloader.StartUpdateCheck(fetch2);
|
||||||
downloader.StartUpdateCheck(fetch3);
|
downloader.StartUpdateCheck(fetch3);
|
||||||
downloader.StartUpdateCheck(fetch4);
|
downloader.StartUpdateCheck(fetch4);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
// The first fetch will fail.
|
// The first fetch will fail.
|
||||||
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
|
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
|
||||||
@@ -765,7 +779,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->set_status(net::URLRequestStatus());
|
fetcher->set_status(net::URLRequestStatus());
|
||||||
fetcher->set_response_code(400);
|
fetcher->set_response_code(400);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
Mock::VerifyAndClearExpectations(&delegate);
|
Mock::VerifyAndClearExpectations(&delegate);
|
||||||
|
|
||||||
// The second fetch gets invalid data.
|
// The second fetch gets invalid data.
|
||||||
@@ -780,7 +794,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->set_response_code(200);
|
fetcher->set_response_code(200);
|
||||||
fetcher->SetResponseString(kInvalidXml);
|
fetcher->SetResponseString(kInvalidXml);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
Mock::VerifyAndClearExpectations(&delegate);
|
Mock::VerifyAndClearExpectations(&delegate);
|
||||||
|
|
||||||
// The third fetcher doesn't have an update available.
|
// The third fetcher doesn't have an update available.
|
||||||
@@ -807,7 +821,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->set_response_code(200);
|
fetcher->set_response_code(200);
|
||||||
fetcher->SetResponseString(kNoUpdate);
|
fetcher->SetResponseString(kNoUpdate);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
Mock::VerifyAndClearExpectations(&delegate);
|
Mock::VerifyAndClearExpectations(&delegate);
|
||||||
|
|
||||||
// The last fetcher has an update.
|
// The last fetcher has an update.
|
||||||
@@ -832,7 +846,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->set_response_code(200);
|
fetcher->set_response_code(200);
|
||||||
fetcher->SetResponseString(kUpdateAvailable);
|
fetcher->SetResponseString(kUpdateAvailable);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
Mock::VerifyAndClearExpectations(&delegate);
|
Mock::VerifyAndClearExpectations(&delegate);
|
||||||
|
|
||||||
// Verify that the downloader decided to update this extension.
|
// Verify that the downloader decided to update this extension.
|
||||||
@@ -843,7 +857,8 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
void TestSingleExtensionDownloading(bool pending) {
|
void TestSingleExtensionDownloading(bool pending) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
net::TestURLFetcher* fetcher = NULL;
|
net::TestURLFetcher* fetcher = NULL;
|
||||||
scoped_ptr<ServiceForDownloadTests> service(new ServiceForDownloadTests);
|
scoped_ptr<ServiceForDownloadTests> service(
|
||||||
|
new ServiceForDownloadTests(prefs_.get()));
|
||||||
ExtensionUpdater updater(service.get(), service->extension_prefs(),
|
ExtensionUpdater updater(service.get(), service->extension_prefs(),
|
||||||
service->pref_service(),
|
service->pref_service(),
|
||||||
service->profile(),
|
service->profile(),
|
||||||
@@ -885,7 +900,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->SetResponseFilePath(extension_file_path);
|
fetcher->SetResponseFilePath(extension_file_path);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
|
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
// Expect that ExtensionUpdater asked the mock extensions service to install
|
// Expect that ExtensionUpdater asked the mock extensions service to install
|
||||||
// a file with the test data for the right id.
|
// a file with the test data for the right id.
|
||||||
@@ -899,7 +914,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
void TestBlacklistDownloading() {
|
void TestBlacklistDownloading() {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
net::TestURLFetcher* fetcher = NULL;
|
net::TestURLFetcher* fetcher = NULL;
|
||||||
ServiceForBlacklistTests service;
|
ServiceForBlacklistTests service(prefs_.get());
|
||||||
ExtensionUpdater updater(
|
ExtensionUpdater updater(
|
||||||
&service, service.extension_prefs(), service.pref_service(),
|
&service, service.extension_prefs(), service.pref_service(),
|
||||||
service.profile(), kUpdateFrequencySecs);
|
service.profile(), kUpdateFrequencySecs);
|
||||||
@@ -930,7 +945,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->SetResponseString(extension_data);
|
fetcher->SetResponseString(extension_data);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
|
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
// The updater should have called extension service to process the
|
// The updater should have called extension service to process the
|
||||||
// blacklist.
|
// blacklist.
|
||||||
@@ -947,7 +962,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
void TestMultipleExtensionDownloading(bool updates_start_running) {
|
void TestMultipleExtensionDownloading(bool updates_start_running) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
net::TestURLFetcher* fetcher = NULL;
|
net::TestURLFetcher* fetcher = NULL;
|
||||||
ServiceForDownloadTests service;
|
ServiceForDownloadTests service(prefs_.get());
|
||||||
ExtensionUpdater updater(
|
ExtensionUpdater updater(
|
||||||
&service, service.extension_prefs(), service.pref_service(),
|
&service, service.extension_prefs(), service.pref_service(),
|
||||||
service.profile(), kUpdateFrequencySecs);
|
service.profile(), kUpdateFrequencySecs);
|
||||||
@@ -1017,14 +1032,14 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->SetResponseFilePath(extension_file_path);
|
fetcher->SetResponseFilePath(extension_file_path);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
|
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
// Expect that the service was asked to do an install with the right data.
|
// Expect that the service was asked to do an install with the right data.
|
||||||
FilePath tmpfile_path = service.install_path();
|
FilePath tmpfile_path = service.install_path();
|
||||||
EXPECT_FALSE(tmpfile_path.empty());
|
EXPECT_FALSE(tmpfile_path.empty());
|
||||||
EXPECT_EQ(id1, service.extension_id());
|
EXPECT_EQ(id1, service.extension_id());
|
||||||
EXPECT_EQ(url1, service.download_url());
|
EXPECT_EQ(url1, service.download_url());
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
// Make sure the second fetch finished and asked the service to do an
|
// Make sure the second fetch finished and asked the service to do an
|
||||||
// update.
|
// update.
|
||||||
@@ -1038,7 +1053,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
fetcher->set_response_code(200);
|
fetcher->set_response_code(200);
|
||||||
fetcher->SetResponseFilePath(extension_file_path2);
|
fetcher->SetResponseFilePath(extension_file_path2);
|
||||||
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
fetcher->delegate()->OnURLFetchComplete(fetcher);
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
|
|
||||||
if (updates_start_running) {
|
if (updates_start_running) {
|
||||||
EXPECT_TRUE(updater.crx_install_is_running_);
|
EXPECT_TRUE(updater.crx_install_is_running_);
|
||||||
@@ -1116,7 +1131,8 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
|
|
||||||
// Set up 2 mock extensions, one with a google.com update url and one
|
// Set up 2 mock extensions, one with a google.com update url and one
|
||||||
// without.
|
// without.
|
||||||
ServiceForManifestTests service;
|
prefs_.reset(new TestExtensionPrefs(loop_.message_loop_proxy()));
|
||||||
|
ServiceForManifestTests service(prefs_.get());
|
||||||
ExtensionList tmp;
|
ExtensionList tmp;
|
||||||
GURL url1("http://clients2.google.com/service/update2/crx");
|
GURL url1("http://clients2.google.com/service/update2/crx");
|
||||||
GURL url2("http://www.somewebsite.com");
|
GURL url2("http://www.somewebsite.com");
|
||||||
@@ -1228,6 +1244,8 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
// queries.
|
// queries.
|
||||||
EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
|
EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This makes sure that the extension updater properly stores the results
|
// This makes sure that the extension updater properly stores the results
|
||||||
@@ -1235,7 +1253,7 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
// the first time we fetched the extension, or 2) We sent a ping value of
|
// the first time we fetched the extension, or 2) We sent a ping value of
|
||||||
// >= 1 day for the extension.
|
// >= 1 day for the extension.
|
||||||
void TestHandleManifestResults() {
|
void TestHandleManifestResults() {
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
GURL update_url("http://www.google.com/manifest");
|
GURL update_url("http://www.google.com/manifest");
|
||||||
ExtensionList tmp;
|
ExtensionList tmp;
|
||||||
service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
|
service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
|
||||||
@@ -1265,6 +1283,9 @@ class ExtensionUpdaterTest : public testing::Test {
|
|||||||
EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
|
EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
scoped_ptr<TestExtensionPrefs> prefs_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageLoop loop_;
|
MessageLoop loop_;
|
||||||
content::TestBrowserThread ui_thread_;
|
content::TestBrowserThread ui_thread_;
|
||||||
@@ -1345,7 +1366,7 @@ TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
|
|||||||
|
|
||||||
TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
|
TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
ExtensionUpdater updater(&service, service.extension_prefs(),
|
ExtensionUpdater updater(&service, service.extension_prefs(),
|
||||||
service.pref_service(), service.profile(),
|
service.pref_service(), service.profile(),
|
||||||
kUpdateFrequencySecs);
|
kUpdateFrequencySecs);
|
||||||
@@ -1376,7 +1397,7 @@ TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
|
|||||||
|
|
||||||
TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
|
TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
ExtensionUpdater updater(&service, service.extension_prefs(),
|
ExtensionUpdater updater(&service, service.extension_prefs(),
|
||||||
service.pref_service(), service.profile(),
|
service.pref_service(), service.profile(),
|
||||||
kUpdateFrequencySecs);
|
kUpdateFrequencySecs);
|
||||||
@@ -1414,7 +1435,7 @@ TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
|
|||||||
|
|
||||||
TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
|
TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
MockService service;
|
MockService service(prefs_.get());
|
||||||
MockExtensionDownloaderDelegate delegate;
|
MockExtensionDownloaderDelegate delegate;
|
||||||
scoped_ptr<ExtensionDownloader> downloader(
|
scoped_ptr<ExtensionDownloader> downloader(
|
||||||
new ExtensionDownloader(&delegate, service.request_context()));
|
new ExtensionDownloader(&delegate, service.request_context()));
|
||||||
@@ -1466,7 +1487,7 @@ TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
|
|||||||
|
|
||||||
TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
|
TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
MockService service;
|
MockService service(prefs_.get());
|
||||||
MockExtensionDownloaderDelegate delegate;
|
MockExtensionDownloaderDelegate delegate;
|
||||||
ExtensionDownloader downloader(&delegate, service.request_context());
|
ExtensionDownloader downloader(&delegate, service.request_context());
|
||||||
|
|
||||||
@@ -1480,7 +1501,7 @@ TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
|
TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
|
||||||
ServiceForManifestTests service;
|
ServiceForManifestTests service(prefs_.get());
|
||||||
net::TestURLFetcherFactory factory;
|
net::TestURLFetcherFactory factory;
|
||||||
ExtensionUpdater updater(
|
ExtensionUpdater updater(
|
||||||
&service, service.extension_prefs(), service.pref_service(),
|
&service, service.extension_prefs(), service.pref_service(),
|
||||||
@@ -1492,7 +1513,7 @@ TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
|
|||||||
EXPECT_TRUE(updater.WillCheckSoon());
|
EXPECT_TRUE(updater.WillCheckSoon());
|
||||||
updater.CheckSoon();
|
updater.CheckSoon();
|
||||||
EXPECT_TRUE(updater.WillCheckSoon());
|
EXPECT_TRUE(updater.WillCheckSoon());
|
||||||
RunAllPending();
|
RunUntilIdle();
|
||||||
EXPECT_FALSE(updater.WillCheckSoon());
|
EXPECT_FALSE(updater.WillCheckSoon());
|
||||||
updater.CheckSoon();
|
updater.CheckSoon();
|
||||||
EXPECT_TRUE(updater.WillCheckSoon());
|
EXPECT_TRUE(updater.WillCheckSoon());
|
||||||
|
@@ -1723,27 +1723,11 @@ bool MetricsService::UmaMetricsProperlyShutdown() {
|
|||||||
return clean_shutdown_status_ == CLEANLY_SHUTDOWN;
|
return clean_shutdown_status_ == CLEANLY_SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use in hack in LogCleanShutdown.
|
|
||||||
static void Signal(base::WaitableEvent* event) {
|
|
||||||
event->Signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetricsService::LogCleanShutdown() {
|
void MetricsService::LogCleanShutdown() {
|
||||||
// Redundant hack to write pref ASAP.
|
// Redundant hack to write pref ASAP.
|
||||||
PrefService* pref = g_browser_process->local_state();
|
PrefService* pref = g_browser_process->local_state();
|
||||||
pref->SetBoolean(prefs::kStabilityExitedCleanly, true);
|
pref->SetBoolean(prefs::kStabilityExitedCleanly, true);
|
||||||
pref->CommitPendingWrite();
|
pref->CommitPendingWrite();
|
||||||
// Hack: TBD: Remove this wait.
|
|
||||||
// We are so concerned that the pref gets written, we are now willing to stall
|
|
||||||
// the UI thread until we get assurance that a pref-writing task has
|
|
||||||
// completed.
|
|
||||||
base::WaitableEvent done_writing(false, false);
|
|
||||||
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
|
|
||||||
base::Bind(Signal, &done_writing));
|
|
||||||
// http://crbug.com/124954
|
|
||||||
base::ThreadRestrictions::ScopedAllowWait allow_wait;
|
|
||||||
done_writing.TimedWait(base::TimeDelta::FromHours(1));
|
|
||||||
|
|
||||||
// Redundant setting to assure that we always reset this value at shutdown
|
// Redundant setting to assure that we always reset this value at shutdown
|
||||||
// (and that we don't use some alternate path, and not call LogCleanShutdown).
|
// (and that we don't use some alternate path, and not call LogCleanShutdown).
|
||||||
clean_shutdown_status_ = CLEANLY_SHUTDOWN;
|
clean_shutdown_status_ = CLEANLY_SHUTDOWN;
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include "chrome/browser/policy/managed_mode_policy_provider.h"
|
#include "chrome/browser/policy/managed_mode_policy_provider.h"
|
||||||
|
|
||||||
#include "base/prefs/json_pref_store.h"
|
#include "base/prefs/json_pref_store.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "chrome/browser/policy/policy_bundle.h"
|
#include "chrome/browser/policy/policy_bundle.h"
|
||||||
#include "chrome/browser/profiles/profile.h"
|
#include "chrome/browser/profiles/profile.h"
|
||||||
#include "chrome/common/chrome_constants.h"
|
#include "chrome/common/chrome_constants.h"
|
||||||
@@ -18,12 +19,11 @@ namespace policy {
|
|||||||
const char ManagedModePolicyProvider::kPolicies[] = "policies";
|
const char ManagedModePolicyProvider::kPolicies[] = "policies";
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ManagedModePolicyProvider* ManagedModePolicyProvider::Create(Profile* profile) {
|
ManagedModePolicyProvider* ManagedModePolicyProvider::Create(
|
||||||
JsonPrefStore* pref_store =
|
Profile* profile,
|
||||||
new JsonPrefStore(profile->GetPath().Append(
|
base::SequencedTaskRunner* sequenced_task_runner) {
|
||||||
chrome::kManagedModePolicyFilename),
|
FilePath path = profile->GetPath().Append(chrome::kManagedModePolicyFilename);
|
||||||
BrowserThread::GetMessageLoopProxyForThread(
|
JsonPrefStore* pref_store = new JsonPrefStore(path, sequenced_task_runner);
|
||||||
BrowserThread::FILE));
|
|
||||||
return new ManagedModePolicyProvider(pref_store);
|
return new ManagedModePolicyProvider(pref_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
class Profile;
|
class Profile;
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
|
}
|
||||||
|
|
||||||
namespace policy {
|
namespace policy {
|
||||||
|
|
||||||
// This class sets policies that are defined by a local user via "Managed Mode".
|
// This class sets policies that are defined by a local user via "Managed Mode".
|
||||||
@@ -25,8 +29,12 @@ class ManagedModePolicyProvider
|
|||||||
static const char kPolicies[];
|
static const char kPolicies[];
|
||||||
|
|
||||||
// Creates a new ManagedModePolicyProvider that caches its policies in a JSON
|
// Creates a new ManagedModePolicyProvider that caches its policies in a JSON
|
||||||
// file inside the profile folder.
|
// file inside the profile folder. |sequenced_task_runner| ensures that all
|
||||||
static ManagedModePolicyProvider* Create(Profile* profile);
|
// file I/O operations are executed in the order that does not collide
|
||||||
|
// with Profile's file operations.
|
||||||
|
static ManagedModePolicyProvider* Create(
|
||||||
|
Profile* profile,
|
||||||
|
base::SequencedTaskRunner* sequenced_task_runner);
|
||||||
|
|
||||||
// Use this constructor to inject a different PrefStore (e.g. for testing).
|
// Use this constructor to inject a different PrefStore (e.g. for testing).
|
||||||
explicit ManagedModePolicyProvider(PersistentPrefStore* store);
|
explicit ManagedModePolicyProvider(PersistentPrefStore* store);
|
||||||
|
@@ -123,6 +123,7 @@ PrefServiceBase* PrefServiceBase::FromBrowserContext(BrowserContext* context) {
|
|||||||
// static
|
// static
|
||||||
PrefService* PrefService::CreatePrefService(
|
PrefService* PrefService::CreatePrefService(
|
||||||
const FilePath& pref_filename,
|
const FilePath& pref_filename,
|
||||||
|
base::SequencedTaskRunner* pref_io_task_runner,
|
||||||
policy::PolicyService* policy_service,
|
policy::PolicyService* policy_service,
|
||||||
PrefStore* extension_prefs,
|
PrefStore* extension_prefs,
|
||||||
bool async) {
|
bool async) {
|
||||||
@@ -156,8 +157,7 @@ PrefService* PrefService::CreatePrefService(
|
|||||||
CommandLinePrefStore* command_line =
|
CommandLinePrefStore* command_line =
|
||||||
new CommandLinePrefStore(CommandLine::ForCurrentProcess());
|
new CommandLinePrefStore(CommandLine::ForCurrentProcess());
|
||||||
JsonPrefStore* user = new JsonPrefStore(
|
JsonPrefStore* user = new JsonPrefStore(
|
||||||
pref_filename,
|
pref_filename, pref_io_task_runner);
|
||||||
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
|
|
||||||
DefaultPrefStore* default_pref_store = new DefaultPrefStore();
|
DefaultPrefStore* default_pref_store = new DefaultPrefStore();
|
||||||
|
|
||||||
PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
|
PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
|
||||||
|
@@ -33,6 +33,10 @@ class PrefServiceObserver;
|
|||||||
class PrefStore;
|
class PrefStore;
|
||||||
class PrefValueStore;
|
class PrefValueStore;
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
|
}
|
||||||
|
|
||||||
namespace syncer {
|
namespace syncer {
|
||||||
class SyncableService;
|
class SyncableService;
|
||||||
}
|
}
|
||||||
@@ -110,10 +114,12 @@ class PrefService : public PrefServiceBase, public base::NonThreadSafe {
|
|||||||
// the created PrefService or NULL if creation has failed. Note, it is
|
// the created PrefService or NULL if creation has failed. Note, it is
|
||||||
// guaranteed that in asynchronous version initialization happens after this
|
// guaranteed that in asynchronous version initialization happens after this
|
||||||
// function returned.
|
// function returned.
|
||||||
static PrefService* CreatePrefService(const FilePath& pref_filename,
|
static PrefService* CreatePrefService(
|
||||||
policy::PolicyService* policy_service,
|
const FilePath& pref_filename,
|
||||||
PrefStore* extension_pref_store,
|
base::SequencedTaskRunner* pref_io_task_runner,
|
||||||
bool async);
|
policy::PolicyService* policy_service,
|
||||||
|
PrefStore* extension_pref_store,
|
||||||
|
bool async);
|
||||||
|
|
||||||
// Creates an incognito copy of the pref service that shares most pref stores
|
// Creates an incognito copy of the pref service that shares most pref stores
|
||||||
// but uses a fresh non-persistent overlay for the user pref store and an
|
// but uses a fresh non-persistent overlay for the user pref store and an
|
||||||
|
@@ -77,16 +77,17 @@ PrefServiceMockBuilder::WithCommandLine(CommandLine* command_line) {
|
|||||||
|
|
||||||
PrefServiceMockBuilder&
|
PrefServiceMockBuilder&
|
||||||
PrefServiceMockBuilder::WithUserFilePrefs(const FilePath& prefs_file) {
|
PrefServiceMockBuilder::WithUserFilePrefs(const FilePath& prefs_file) {
|
||||||
return WithUserFilePrefs(prefs_file,
|
return WithUserFilePrefs(
|
||||||
BrowserThread::GetMessageLoopProxyForThread(
|
prefs_file,
|
||||||
BrowserThread::FILE));
|
JsonPrefStore::GetTaskRunnerForFile(prefs_file,
|
||||||
|
BrowserThread::GetBlockingPool()));
|
||||||
}
|
}
|
||||||
|
|
||||||
PrefServiceMockBuilder&
|
PrefServiceMockBuilder&
|
||||||
PrefServiceMockBuilder::WithUserFilePrefs(
|
PrefServiceMockBuilder::WithUserFilePrefs(
|
||||||
const FilePath& prefs_file,
|
const FilePath& prefs_file,
|
||||||
base::MessageLoopProxy* message_loop_proxy) {
|
base::SequencedTaskRunner* task_runner) {
|
||||||
user_prefs_ = new JsonPrefStore(prefs_file, message_loop_proxy);
|
user_prefs_ = new JsonPrefStore(prefs_file, task_runner);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ class FilePath;
|
|||||||
class PrefService;
|
class PrefService;
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class MessageLoopProxy;
|
class SequencedTaskRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace policy {
|
namespace policy {
|
||||||
@@ -48,10 +48,11 @@ class PrefServiceMockBuilder {
|
|||||||
PrefServiceMockBuilder& WithCommandLine(CommandLine* command_line);
|
PrefServiceMockBuilder& WithCommandLine(CommandLine* command_line);
|
||||||
|
|
||||||
// Specifies to use an actual file-backed user pref store.
|
// Specifies to use an actual file-backed user pref store.
|
||||||
|
// TODO(zelidrag): Remove the first overloaded method below.
|
||||||
PrefServiceMockBuilder& WithUserFilePrefs(const FilePath& prefs_file);
|
PrefServiceMockBuilder& WithUserFilePrefs(const FilePath& prefs_file);
|
||||||
PrefServiceMockBuilder& WithUserFilePrefs(
|
PrefServiceMockBuilder& WithUserFilePrefs(
|
||||||
const FilePath& prefs_file,
|
const FilePath& prefs_file,
|
||||||
base::MessageLoopProxy* message_loop_proxy);
|
base::SequencedTaskRunner* task_runner);
|
||||||
|
|
||||||
// Creates the PrefService, invalidating the entire builder configuration.
|
// Creates the PrefService, invalidating the entire builder configuration.
|
||||||
PrefService* Create();
|
PrefService* Create();
|
||||||
|
@@ -315,7 +315,7 @@ TEST_F(PrefServiceUserFilePrefsTest, PreserveEmptyValue) {
|
|||||||
pref_file));
|
pref_file));
|
||||||
|
|
||||||
PrefServiceMockBuilder builder;
|
PrefServiceMockBuilder builder;
|
||||||
builder.WithUserFilePrefs(pref_file, base::MessageLoopProxy::current());
|
builder.WithUserFilePrefs(pref_file, message_loop_.message_loop_proxy());
|
||||||
scoped_ptr<PrefService> prefs(builder.Create());
|
scoped_ptr<PrefService> prefs(builder.Create());
|
||||||
|
|
||||||
// Register testing prefs.
|
// Register testing prefs.
|
||||||
@@ -344,7 +344,7 @@ TEST_F(PrefServiceUserFilePrefsTest, PreserveEmptyValue) {
|
|||||||
|
|
||||||
// Write to file.
|
// Write to file.
|
||||||
prefs->CommitPendingWrite();
|
prefs->CommitPendingWrite();
|
||||||
MessageLoop::current()->RunAllPending();
|
message_loop_.RunUntilIdle();
|
||||||
|
|
||||||
// Compare to expected output.
|
// Compare to expected output.
|
||||||
FilePath golden_output_file =
|
FilePath golden_output_file =
|
||||||
|
@@ -190,6 +190,11 @@ FilePath OffTheRecordProfileImpl::GetPath() {
|
|||||||
return profile_->GetPath();
|
return profile_->GetPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoped_refptr<base::SequencedTaskRunner>
|
||||||
|
OffTheRecordProfileImpl::GetIOTaskRunner() {
|
||||||
|
return profile_->GetIOTaskRunner();
|
||||||
|
}
|
||||||
|
|
||||||
bool OffTheRecordProfileImpl::IsOffTheRecord() const {
|
bool OffTheRecordProfileImpl::IsOffTheRecord() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -87,6 +87,7 @@ class OffTheRecordProfileImpl : public Profile,
|
|||||||
|
|
||||||
// content::BrowserContext implementation:
|
// content::BrowserContext implementation:
|
||||||
virtual FilePath GetPath() OVERRIDE;
|
virtual FilePath GetPath() OVERRIDE;
|
||||||
|
virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() OVERRIDE;
|
||||||
virtual bool IsOffTheRecord() const OVERRIDE;
|
virtual bool IsOffTheRecord() const OVERRIDE;
|
||||||
virtual content::DownloadManagerDelegate*
|
virtual content::DownloadManagerDelegate*
|
||||||
GetDownloadManagerDelegate() OVERRIDE;
|
GetDownloadManagerDelegate() OVERRIDE;
|
||||||
|
@@ -35,6 +35,7 @@ class TabContentsProvider;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
class Time;
|
class Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +141,10 @@ class Profile : public content::BrowserContext {
|
|||||||
// time.
|
// time.
|
||||||
static void RegisterUserPrefs(PrefService* prefs);
|
static void RegisterUserPrefs(PrefService* prefs);
|
||||||
|
|
||||||
|
// Gets task runner for I/O operations associated with |profile|.
|
||||||
|
static scoped_refptr<base::SequencedTaskRunner> GetTaskRunnerForProfile(
|
||||||
|
Profile* profile);
|
||||||
|
|
||||||
// Create a new profile given a path. If |create_mode| is
|
// Create a new profile given a path. If |create_mode| is
|
||||||
// CREATE_MODE_ASYNCHRONOUS then the profile is initialized asynchronously.
|
// CREATE_MODE_ASYNCHRONOUS then the profile is initialized asynchronously.
|
||||||
static Profile* CreateProfile(const FilePath& path,
|
static Profile* CreateProfile(const FilePath& path,
|
||||||
@@ -157,6 +162,10 @@ class Profile : public content::BrowserContext {
|
|||||||
// Typesafe upcast.
|
// Typesafe upcast.
|
||||||
virtual TestingProfile* AsTestingProfile();
|
virtual TestingProfile* AsTestingProfile();
|
||||||
|
|
||||||
|
// Returns sequenced task runner where browser context dependent I/O
|
||||||
|
// operations should be performed.
|
||||||
|
virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() = 0;
|
||||||
|
|
||||||
// Returns the name associated with this profile. This name is displayed in
|
// Returns the name associated with this profile. This name is displayed in
|
||||||
// the browser frame.
|
// the browser frame.
|
||||||
virtual std::string GetProfileName() = 0;
|
virtual std::string GetProfileName() = 0;
|
||||||
|
@@ -13,10 +13,13 @@
|
|||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
|
#include "base/prefs/json_pref_store.h"
|
||||||
#include "base/string_number_conversions.h"
|
#include "base/string_number_conversions.h"
|
||||||
#include "base/string_tokenizer.h"
|
#include "base/string_tokenizer.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
#include "base/stringprintf.h"
|
#include "base/stringprintf.h"
|
||||||
|
#include "base/synchronization/waitable_event.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "base/utf_string_conversions.h"
|
#include "base/utf_string_conversions.h"
|
||||||
#include "base/version.h"
|
#include "base/version.h"
|
||||||
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
|
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
|
||||||
@@ -149,6 +152,38 @@ static const char kReadmeText[] =
|
|||||||
const char* const kPrefExitTypeCrashed = "Crashed";
|
const char* const kPrefExitTypeCrashed = "Crashed";
|
||||||
const char* const kPrefExitTypeSessionEnded = "SessionEnded";
|
const char* const kPrefExitTypeSessionEnded = "SessionEnded";
|
||||||
|
|
||||||
|
// Helper method needed because PostTask cannot currently take a Callback
|
||||||
|
// function with non-void return type.
|
||||||
|
void CreateDirectoryAndSignal(const FilePath& path,
|
||||||
|
base::WaitableEvent* done_creating) {
|
||||||
|
DVLOG(1) << "Creating directory " << path.value();
|
||||||
|
file_util::CreateDirectory(path);
|
||||||
|
done_creating->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on
|
||||||
|
// blocking I/O pool.
|
||||||
|
void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) {
|
||||||
|
done_creating->Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiates creation of profile directory on |sequenced_task_runner| and
|
||||||
|
// ensures that FILE thread is blocked until that operation finishes.
|
||||||
|
void CreateProfileDirectory(base::SequencedTaskRunner* sequenced_task_runner,
|
||||||
|
const FilePath& path) {
|
||||||
|
base::WaitableEvent* done_creating = new base::WaitableEvent(false, false);
|
||||||
|
sequenced_task_runner->PostTask(FROM_HERE,
|
||||||
|
base::Bind(&CreateDirectoryAndSignal,
|
||||||
|
path,
|
||||||
|
done_creating));
|
||||||
|
// Block the FILE thread until directory is created on I/O pool to make sure
|
||||||
|
// that we don't attempt any operation until that part completes.
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::FILE, FROM_HERE,
|
||||||
|
base::Bind(&BlockFileThreadOnDirectoryCreate,
|
||||||
|
base::Owned(done_creating)));
|
||||||
|
}
|
||||||
|
|
||||||
FilePath GetCachePath(const FilePath& base) {
|
FilePath GetCachePath(const FilePath& base) {
|
||||||
return base.Append(chrome::kCacheDirname);
|
return base.Append(chrome::kCacheDirname);
|
||||||
}
|
}
|
||||||
@@ -199,12 +234,15 @@ std::string ExitTypeToSessionTypePrefValue(Profile::ExitType type) {
|
|||||||
Profile* Profile::CreateProfile(const FilePath& path,
|
Profile* Profile::CreateProfile(const FilePath& path,
|
||||||
Delegate* delegate,
|
Delegate* delegate,
|
||||||
CreateMode create_mode) {
|
CreateMode create_mode) {
|
||||||
|
// Get sequenced task runner for making sure that file operations of
|
||||||
|
// this profile (defined by |path|) are executed in expected order
|
||||||
|
// (what was previously assured by the FILE thread).
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner =
|
||||||
|
JsonPrefStore::GetTaskRunnerForFile(path,
|
||||||
|
BrowserThread::GetBlockingPool());
|
||||||
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
|
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
|
||||||
DCHECK(delegate);
|
DCHECK(delegate);
|
||||||
// This is safe while all file operations are done on the FILE thread.
|
CreateProfileDirectory(sequenced_task_runner, path);
|
||||||
BrowserThread::PostTask(
|
|
||||||
BrowserThread::FILE, FROM_HERE,
|
|
||||||
base::Bind(base::IgnoreResult(&file_util::CreateDirectory), path));
|
|
||||||
} else if (create_mode == CREATE_MODE_SYNCHRONOUS) {
|
} else if (create_mode == CREATE_MODE_SYNCHRONOUS) {
|
||||||
if (!file_util::PathExists(path)) {
|
if (!file_util::PathExists(path)) {
|
||||||
// TODO(tc): http://b/1094718 Bad things happen if we can't write to the
|
// TODO(tc): http://b/1094718 Bad things happen if we can't write to the
|
||||||
@@ -217,7 +255,7 @@ Profile* Profile::CreateProfile(const FilePath& path,
|
|||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProfileImpl(path, delegate, create_mode);
|
return new ProfileImpl(path, delegate, create_mode, sequenced_task_runner);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -270,9 +308,11 @@ void ProfileImpl::RegisterUserPrefs(PrefService* prefs) {
|
|||||||
PrefService::SYNCABLE_PREF);
|
PrefService::SYNCABLE_PREF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileImpl::ProfileImpl(const FilePath& path,
|
ProfileImpl::ProfileImpl(
|
||||||
Delegate* delegate,
|
const FilePath& path,
|
||||||
CreateMode create_mode)
|
Delegate* delegate,
|
||||||
|
CreateMode create_mode,
|
||||||
|
base::SequencedTaskRunner* sequenced_task_runner)
|
||||||
: path_(path),
|
: path_(path),
|
||||||
ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
|
ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
|
||||||
host_content_settings_map_(NULL),
|
host_content_settings_map_(NULL),
|
||||||
@@ -307,7 +347,7 @@ ProfileImpl::ProfileImpl(const FilePath& path,
|
|||||||
if (cloud_policy_manager_)
|
if (cloud_policy_manager_)
|
||||||
cloud_policy_manager_->Init();
|
cloud_policy_manager_->Init();
|
||||||
managed_mode_policy_provider_.reset(
|
managed_mode_policy_provider_.reset(
|
||||||
policy::ManagedModePolicyProvider::Create(this));
|
policy::ManagedModePolicyProvider::Create(this, sequenced_task_runner));
|
||||||
managed_mode_policy_provider_->Init();
|
managed_mode_policy_provider_->Init();
|
||||||
policy_service_ = connector->CreatePolicyService(this);
|
policy_service_ = connector->CreatePolicyService(this);
|
||||||
#else
|
#else
|
||||||
@@ -317,6 +357,7 @@ ProfileImpl::ProfileImpl(const FilePath& path,
|
|||||||
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
|
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
|
||||||
prefs_.reset(PrefService::CreatePrefService(
|
prefs_.reset(PrefService::CreatePrefService(
|
||||||
GetPrefFilePath(),
|
GetPrefFilePath(),
|
||||||
|
sequenced_task_runner,
|
||||||
policy_service_.get(),
|
policy_service_.get(),
|
||||||
new ExtensionPrefStore(
|
new ExtensionPrefStore(
|
||||||
ExtensionPrefValueMapFactory::GetForProfile(this), false),
|
ExtensionPrefValueMapFactory::GetForProfile(this), false),
|
||||||
@@ -331,6 +372,7 @@ ProfileImpl::ProfileImpl(const FilePath& path,
|
|||||||
// Load prefs synchronously.
|
// Load prefs synchronously.
|
||||||
prefs_.reset(PrefService::CreatePrefService(
|
prefs_.reset(PrefService::CreatePrefService(
|
||||||
GetPrefFilePath(),
|
GetPrefFilePath(),
|
||||||
|
sequenced_task_runner,
|
||||||
policy_service_.get(),
|
policy_service_.get(),
|
||||||
new ExtensionPrefStore(
|
new ExtensionPrefStore(
|
||||||
ExtensionPrefValueMapFactory::GetForProfile(this), false),
|
ExtensionPrefValueMapFactory::GetForProfile(this), false),
|
||||||
@@ -354,10 +396,10 @@ void ProfileImpl::DoFinalInit(bool is_new_profile) {
|
|||||||
// to PathService.
|
// to PathService.
|
||||||
chrome::GetUserCacheDirectory(path_, &base_cache_path_);
|
chrome::GetUserCacheDirectory(path_, &base_cache_path_);
|
||||||
// Always create the cache directory asynchronously.
|
// Always create the cache directory asynchronously.
|
||||||
BrowserThread::PostTask(
|
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner =
|
||||||
BrowserThread::FILE, FROM_HERE,
|
JsonPrefStore::GetTaskRunnerForFile(base_cache_path_,
|
||||||
base::Bind(base::IgnoreResult(&file_util::CreateDirectory),
|
BrowserThread::GetBlockingPool());
|
||||||
base_cache_path_));
|
CreateProfileDirectory(sequenced_task_runner, base_cache_path_);
|
||||||
|
|
||||||
// Now that the profile is hooked up to receive pref change notifications to
|
// Now that the profile is hooked up to receive pref change notifications to
|
||||||
// kGoogleServicesUsername, initialize components that depend on it to reflect
|
// kGoogleServicesUsername, initialize components that depend on it to reflect
|
||||||
@@ -562,6 +604,11 @@ FilePath ProfileImpl::GetPath() {
|
|||||||
return path_;
|
return path_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> ProfileImpl::GetIOTaskRunner() {
|
||||||
|
return JsonPrefStore::GetTaskRunnerForFile(
|
||||||
|
GetPath(), BrowserThread::GetBlockingPool());
|
||||||
|
}
|
||||||
|
|
||||||
bool ProfileImpl::IsOffTheRecord() const {
|
bool ProfileImpl::IsOffTheRecord() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,10 @@ class Preferences;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class SequencedTaskRunner;
|
||||||
|
}
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class SpeechRecognitionPreferences;
|
class SpeechRecognitionPreferences;
|
||||||
}
|
}
|
||||||
@@ -79,6 +83,7 @@ class ProfileImpl : public Profile,
|
|||||||
virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
|
virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
|
||||||
|
|
||||||
// Profile implementation:
|
// Profile implementation:
|
||||||
|
virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() OVERRIDE;
|
||||||
virtual std::string GetProfileName() OVERRIDE;
|
virtual std::string GetProfileName() OVERRIDE;
|
||||||
virtual bool IsOffTheRecord() const OVERRIDE;
|
virtual bool IsOffTheRecord() const OVERRIDE;
|
||||||
virtual Profile* GetOffTheRecordProfile() OVERRIDE;
|
virtual Profile* GetOffTheRecordProfile() OVERRIDE;
|
||||||
@@ -149,7 +154,8 @@ class ProfileImpl : public Profile,
|
|||||||
|
|
||||||
ProfileImpl(const FilePath& path,
|
ProfileImpl(const FilePath& path,
|
||||||
Delegate* delegate,
|
Delegate* delegate,
|
||||||
CreateMode create_mode);
|
CreateMode create_mode,
|
||||||
|
base::SequencedTaskRunner* sequenced_task_runner);
|
||||||
|
|
||||||
// Does final initialization. Should be called after prefs were loaded.
|
// Does final initialization. Should be called after prefs were loaded.
|
||||||
void DoFinalInit(bool is_new_profile);
|
void DoFinalInit(bool is_new_profile);
|
||||||
|
@@ -691,8 +691,9 @@ void CredentialCacheService::LookForCachedCredentialsInAlternateProfile() {
|
|||||||
// Attempt to read cached credentials from the alternate profile. If no file
|
// Attempt to read cached credentials from the alternate profile. If no file
|
||||||
// exists, ReadPrefsAsync() will cause PREF_READ_ERROR_NO_FILE to be returned
|
// exists, ReadPrefsAsync() will cause PREF_READ_ERROR_NO_FILE to be returned
|
||||||
// after initialization is complete.
|
// after initialization is complete.
|
||||||
|
FilePath path = GetCredentialPathInAlternateProfile();
|
||||||
alternate_store_ = new JsonPrefStore(
|
alternate_store_ = new JsonPrefStore(
|
||||||
GetCredentialPathInAlternateProfile(),
|
path,
|
||||||
content::BrowserThread::GetMessageLoopProxyForThread(
|
content::BrowserThread::GetMessageLoopProxyForThread(
|
||||||
content::BrowserThread::FILE));
|
content::BrowserThread::FILE));
|
||||||
alternate_store_observer_ = new AlternateStoreObserver(this,
|
alternate_store_observer_ = new AlternateStoreObserver(this,
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "base/utf_string_conversions.h"
|
#include "base/utf_string_conversions.h"
|
||||||
#include "chrome/app/chrome_command_ids.h"
|
#include "chrome/app/chrome_command_ids.h"
|
||||||
#include "chrome/browser/bookmarks/bookmark_model.h"
|
#include "chrome/browser/bookmarks/bookmark_model.h"
|
||||||
@@ -76,6 +77,7 @@ class BookmarkContextMenuTest : public testing::Test {
|
|||||||
|
|
||||||
ui::Clipboard::DestroyClipboardForCurrentThread();
|
ui::Clipboard::DestroyClipboardForCurrentThread();
|
||||||
|
|
||||||
|
BrowserThread::GetBlockingPool()->FlushForTesting();
|
||||||
// Flush the message loop to make application verifiers happy.
|
// Flush the message loop to make application verifiers happy.
|
||||||
message_loop_.RunAllPending();
|
message_loop_.RunAllPending();
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ const char kServiceStateContent[] =
|
|||||||
|
|
||||||
class ConnectorSettingsTest : public testing::Test {
|
class ConnectorSettingsTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() OVERRIDE {
|
||||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||||
message_loop_proxy_ = base::MessageLoopProxy::current();
|
message_loop_proxy_ = base::MessageLoopProxy::current();
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ class ConnectorSettingsTest : public testing::Test {
|
|||||||
file_util::WriteFile(file_name, content.c_str(), content.size());
|
file_util::WriteFile(file_name, content.c_str(), content.size());
|
||||||
}
|
}
|
||||||
ServiceProcessPrefs* prefs =
|
ServiceProcessPrefs* prefs =
|
||||||
new ServiceProcessPrefs(file_name, message_loop_proxy_.get());
|
new ServiceProcessPrefs(file_name, message_loop_proxy_);
|
||||||
prefs->ReadPrefs();
|
prefs->ReadPrefs();
|
||||||
return prefs;
|
return prefs;
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "base/i18n/rtl.h"
|
#include "base/i18n/rtl.h"
|
||||||
#include "base/memory/singleton.h"
|
#include "base/memory/singleton.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
|
#include "base/prefs/json_pref_store.h"
|
||||||
#include "base/string16.h"
|
#include "base/string16.h"
|
||||||
#include "base/utf_string_conversions.h"
|
#include "base/utf_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
@@ -152,6 +153,7 @@ bool ServiceProcess::Initialize(MessageLoopForUI* message_loop,
|
|||||||
Teardown();
|
Teardown();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
blocking_pool_ = new base::SequencedWorkerPool(3, "ServiceBlocking");
|
||||||
|
|
||||||
request_context_getter_ = new ServiceURLRequestContextGetter();
|
request_context_getter_ = new ServiceURLRequestContextGetter();
|
||||||
|
|
||||||
@@ -159,7 +161,9 @@ bool ServiceProcess::Initialize(MessageLoopForUI* message_loop,
|
|||||||
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
||||||
FilePath pref_path = user_data_dir.Append(chrome::kServiceStateFileName);
|
FilePath pref_path = user_data_dir.Append(chrome::kServiceStateFileName);
|
||||||
service_prefs_.reset(
|
service_prefs_.reset(
|
||||||
new ServiceProcessPrefs(pref_path, file_thread_->message_loop_proxy()));
|
new ServiceProcessPrefs(
|
||||||
|
pref_path,
|
||||||
|
JsonPrefStore::GetTaskRunnerForFile(pref_path, blocking_pool_)));
|
||||||
service_prefs_->ReadPrefs();
|
service_prefs_->ReadPrefs();
|
||||||
|
|
||||||
// Check if a locale override has been specified on the command-line.
|
// Check if a locale override has been specified on the command-line.
|
||||||
@@ -218,6 +222,12 @@ bool ServiceProcess::Teardown() {
|
|||||||
shutdown_event_.Signal();
|
shutdown_event_.Signal();
|
||||||
io_thread_.reset();
|
io_thread_.reset();
|
||||||
file_thread_.reset();
|
file_thread_.reset();
|
||||||
|
|
||||||
|
if (blocking_pool_.get()) {
|
||||||
|
blocking_pool_->Shutdown();
|
||||||
|
blocking_pool_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// The NetworkChangeNotifier must be destroyed after all other threads that
|
// The NetworkChangeNotifier must be destroyed after all other threads that
|
||||||
// might use it have been shut down.
|
// might use it have been shut down.
|
||||||
network_change_notifier_.reset();
|
network_change_notifier_.reset();
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "base/gtest_prod_util.h"
|
#include "base/gtest_prod_util.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "base/threading/sequenced_worker_pool.h"
|
||||||
#include "base/threading/thread.h"
|
#include "base/threading/thread.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
#include "chrome/service/cloud_print/cloud_print_proxy.h"
|
#include "chrome/service/cloud_print/cloud_print_proxy.h"
|
||||||
@@ -123,6 +124,7 @@ class ServiceProcess : public CloudPrintProxy::Client {
|
|||||||
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
|
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
|
||||||
scoped_ptr<base::Thread> io_thread_;
|
scoped_ptr<base::Thread> io_thread_;
|
||||||
scoped_ptr<base::Thread> file_thread_;
|
scoped_ptr<base::Thread> file_thread_;
|
||||||
|
scoped_refptr<base::SequencedWorkerPool> blocking_pool_;
|
||||||
scoped_ptr<CloudPrintProxy> cloud_print_proxy_;
|
scoped_ptr<CloudPrintProxy> cloud_print_proxy_;
|
||||||
scoped_ptr<ServiceProcessPrefs> service_prefs_;
|
scoped_ptr<ServiceProcessPrefs> service_prefs_;
|
||||||
scoped_ptr<ServiceIPCServer> ipc_server_;
|
scoped_ptr<ServiceIPCServer> ipc_server_;
|
||||||
|
@@ -4,12 +4,13 @@
|
|||||||
|
|
||||||
#include "chrome/service/service_process_prefs.h"
|
#include "chrome/service/service_process_prefs.h"
|
||||||
|
|
||||||
|
#include "base/message_loop_proxy.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
|
||||||
ServiceProcessPrefs::ServiceProcessPrefs(
|
ServiceProcessPrefs::ServiceProcessPrefs(
|
||||||
const FilePath& pref_filename,
|
const FilePath& pref_filename,
|
||||||
base::MessageLoopProxy* file_message_loop_proxy)
|
base::SequencedTaskRunner* task_runner)
|
||||||
: prefs_(new JsonPrefStore(pref_filename, file_message_loop_proxy)) {
|
: prefs_(new JsonPrefStore(pref_filename, task_runner)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceProcessPrefs::~ServiceProcessPrefs() {}
|
ServiceProcessPrefs::~ServiceProcessPrefs() {}
|
||||||
|
@@ -12,16 +12,16 @@
|
|||||||
namespace base {
|
namespace base {
|
||||||
class DictionaryValue;
|
class DictionaryValue;
|
||||||
class ListValue;
|
class ListValue;
|
||||||
|
class SequencedTaskRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manages persistent preferences for the service process. This is basically a
|
// Manages persistent preferences for the service process. This is basically a
|
||||||
// thin wrapper around JsonPrefStore for more comfortable use.
|
// thin wrapper around JsonPrefStore for more comfortable use.
|
||||||
class ServiceProcessPrefs {
|
class ServiceProcessPrefs {
|
||||||
public:
|
public:
|
||||||
// |file_message_loop_proxy| is the MessageLoopProxy for a thread on which
|
// |sequenced_task_runner| must be a shutdown-blocking task runner.
|
||||||
// file I/O can be done.
|
|
||||||
ServiceProcessPrefs(const FilePath& pref_filename,
|
ServiceProcessPrefs(const FilePath& pref_filename,
|
||||||
base::MessageLoopProxy* file_message_loop_proxy);
|
base::SequencedTaskRunner* task_runner);
|
||||||
~ServiceProcessPrefs();
|
~ServiceProcessPrefs();
|
||||||
|
|
||||||
// Read preferences from the backing file.
|
// Read preferences from the backing file.
|
||||||
|
@@ -5,29 +5,30 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/message_loop.h"
|
#include "base/message_loop.h"
|
||||||
#include "base/message_loop_proxy.h"
|
|
||||||
#include "base/scoped_temp_dir.h"
|
#include "base/scoped_temp_dir.h"
|
||||||
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "chrome/service/service_process_prefs.h"
|
#include "chrome/service/service_process_prefs.h"
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
class ServiceProcessPrefsTest : public testing::Test {
|
class ServiceProcessPrefsTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() OVERRIDE {
|
||||||
message_loop_proxy_ = base::MessageLoopProxy::current();
|
|
||||||
|
|
||||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||||
|
|
||||||
prefs_.reset(new ServiceProcessPrefs(
|
prefs_.reset(new ServiceProcessPrefs(
|
||||||
temp_dir_.path().AppendASCII("service_process_prefs.txt"),
|
temp_dir_.path().AppendASCII("service_process_prefs.txt"),
|
||||||
message_loop_proxy_.get()));
|
message_loop_.message_loop_proxy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() OVERRIDE {
|
||||||
|
prefs_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The path to temporary directory used to contain the test operations.
|
// The path to temporary directory used to contain the test operations.
|
||||||
ScopedTempDir temp_dir_;
|
ScopedTempDir temp_dir_;
|
||||||
// A message loop that we can use as the file thread message loop.
|
// A message loop that we can use as the file thread message loop.
|
||||||
MessageLoop message_loop_;
|
MessageLoop message_loop_;
|
||||||
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
|
|
||||||
scoped_ptr<ServiceProcessPrefs> prefs_;
|
scoped_ptr<ServiceProcessPrefs> prefs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ TEST_F(ServiceProcessPrefsTest, RetrievePrefs) {
|
|||||||
prefs_->SetBoolean("testb", true);
|
prefs_->SetBoolean("testb", true);
|
||||||
prefs_->SetString("tests", "testvalue");
|
prefs_->SetString("tests", "testvalue");
|
||||||
prefs_->WritePrefs();
|
prefs_->WritePrefs();
|
||||||
MessageLoop::current()->RunAllPending();
|
message_loop_.RunUntilIdle();
|
||||||
prefs_->SetBoolean("testb", false); // overwrite
|
prefs_->SetBoolean("testb", false); // overwrite
|
||||||
prefs_->SetString("tests", ""); // overwrite
|
prefs_->SetString("tests", ""); // overwrite
|
||||||
prefs_->ReadPrefs();
|
prefs_->ReadPrefs();
|
||||||
|
@@ -478,6 +478,10 @@ FilePath TestingProfile::GetPath() {
|
|||||||
return profile_path_;
|
return profile_path_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> TestingProfile::GetIOTaskRunner() {
|
||||||
|
return MessageLoop::current()->message_loop_proxy();
|
||||||
|
}
|
||||||
|
|
||||||
TestingPrefService* TestingProfile::GetTestingPrefService() {
|
TestingPrefService* TestingProfile::GetTestingPrefService() {
|
||||||
if (!prefs_.get())
|
if (!prefs_.get())
|
||||||
CreateTestingPrefService();
|
CreateTestingPrefService();
|
||||||
|
@@ -178,6 +178,7 @@ class TestingProfile : public Profile {
|
|||||||
|
|
||||||
// content::BrowserContext
|
// content::BrowserContext
|
||||||
virtual FilePath GetPath() OVERRIDE;
|
virtual FilePath GetPath() OVERRIDE;
|
||||||
|
virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() OVERRIDE;
|
||||||
virtual bool IsOffTheRecord() const OVERRIDE;
|
virtual bool IsOffTheRecord() const OVERRIDE;
|
||||||
virtual content::DownloadManagerDelegate*
|
virtual content::DownloadManagerDelegate*
|
||||||
GetDownloadManagerDelegate() OVERRIDE;
|
GetDownloadManagerDelegate() OVERRIDE;
|
||||||
|
@@ -739,7 +739,8 @@ class PageLoadTest : public UITest {
|
|||||||
// returned PrefService object.
|
// returned PrefService object.
|
||||||
PrefService* GetLocalState() {
|
PrefService* GetLocalState() {
|
||||||
FilePath path = user_data_dir().Append(chrome::kLocalStateFilename);
|
FilePath path = user_data_dir().Append(chrome::kLocalStateFilename);
|
||||||
return PrefServiceMockBuilder().WithUserFilePrefs(path).Create();
|
return PrefServiceMockBuilder().WithUserFilePrefs(
|
||||||
|
path, MessageLoop::current()->message_loop_proxy()).Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetStabilityMetrics(NavigationMetrics* metrics) {
|
void GetStabilityMetrics(NavigationMetrics* metrics) {
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "base/lazy_instance.h"
|
#include "base/lazy_instance.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
|
#include "base/prefs/json_pref_store.h"
|
||||||
#include "base/scoped_temp_dir.h"
|
#include "base/scoped_temp_dir.h"
|
||||||
#include "base/string_piece.h"
|
#include "base/string_piece.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
@@ -353,8 +354,9 @@ void FilterDisabledTests() {
|
|||||||
// Same as BrowserProcessImpl, but uses custom profile manager.
|
// Same as BrowserProcessImpl, but uses custom profile manager.
|
||||||
class FakeBrowserProcessImpl : public BrowserProcessImpl {
|
class FakeBrowserProcessImpl : public BrowserProcessImpl {
|
||||||
public:
|
public:
|
||||||
explicit FakeBrowserProcessImpl(const CommandLine& command_line)
|
FakeBrowserProcessImpl(base::SequencedTaskRunner* local_state_task_runner,
|
||||||
: BrowserProcessImpl(command_line) {
|
const CommandLine& command_line)
|
||||||
|
: BrowserProcessImpl(local_state_task_runner, command_line) {
|
||||||
profiles_dir_.CreateUniqueTempDir();
|
profiles_dir_.CreateUniqueTempDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +497,13 @@ void FakeExternalTab::Initialize() {
|
|||||||
cmd->AppendSwitch(switches::kDisableWebResources);
|
cmd->AppendSwitch(switches::kDisableWebResources);
|
||||||
cmd->AppendSwitch(switches::kSingleProcess);
|
cmd->AppendSwitch(switches::kSingleProcess);
|
||||||
|
|
||||||
browser_process_.reset(new FakeBrowserProcessImpl(*cmd));
|
FilePath local_state_path;
|
||||||
|
CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path));
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> local_state_task_runner =
|
||||||
|
JsonPrefStore::GetTaskRunnerForFile(local_state_path,
|
||||||
|
BrowserThread::GetBlockingPool());
|
||||||
|
browser_process_.reset(new FakeBrowserProcessImpl(local_state_task_runner,
|
||||||
|
*cmd));
|
||||||
// BrowserProcessImpl's constructor should set g_browser_process.
|
// BrowserProcessImpl's constructor should set g_browser_process.
|
||||||
DCHECK(g_browser_process);
|
DCHECK(g_browser_process);
|
||||||
g_browser_process->SetApplicationLocale("en-US");
|
g_browser_process->SetApplicationLocale("en-US");
|
||||||
|
Reference in New Issue
Block a user