// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/external_pref_extension_loader.h"
#include "app/app_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "content/browser/browser_thread.h"
#include "content/common/json_value_serializer.h"
namespace {
// Caller takes ownership of the returned dictionary.
DictionaryValue* ExtractPrefs(const FilePath& path,
ValueSerializer* serializer) {
std::string error_msg;
Value* extensions = serializer->Deserialize(NULL, &error_msg);
if (!extensions) {
LOG(WARNING) << "Unable to deserialize json data: " << error_msg
<< " In file " << path.value() << " .";
} else {
if (!extensions->IsType(Value::TYPE_DICTIONARY)) {
LOG(WARNING) << "Expected a JSON dictionary in file "
<< path.value() << " .";
} else {
return static_cast<DictionaryValue*>(extensions);
}
}
return new DictionaryValue;
}
} // namespace
ExternalPrefExtensionLoader::ExternalPrefExtensionLoader(int base_path_key)
: base_path_key_(base_path_key) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
const FilePath ExternalPrefExtensionLoader::GetBaseCrxFilePath() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// |base_path_| was set in LoadOnFileThread().
return base_path_;
}
void ExternalPrefExtensionLoader::StartLoading() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
this,
&ExternalPrefExtensionLoader::LoadOnFileThread));
}
void ExternalPrefExtensionLoader::LoadOnFileThread() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
// TODO(skerner): Some values of base_path_key_ will cause
// PathService::Get() to return false, because the path does
// not exist. Find and fix the build/install scripts so that
// this can become a CHECK(). Known examples include chrome
// OS developer builds and linux install packages.
// Tracked as crbug.com/70402 .
scoped_ptr<DictionaryValue> prefs;
if (PathService::Get(base_path_key_, &base_path_)) {
FilePath json_file;
json_file =
base_path_.Append(FILE_PATH_LITERAL("external_extensions.json"));
if (file_util::PathExists(json_file)) {
JSONFileValueSerializer serializer(json_file);
prefs.reset(ExtractPrefs(json_file, &serializer));
}
}
if (!prefs.get())
prefs.reset(new DictionaryValue());
prefs_.reset(prefs.release());
// If we have any records to process, then we must have
// read the .json file. If we read the .json file, then
// we were should have set |base_path_|.
if (!prefs_->empty())
CHECK(!base_path_.empty());
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(
this,
&ExternalPrefExtensionLoader::LoadFinished));
}
ExternalTestingExtensionLoader::ExternalTestingExtensionLoader(
const std::string& json_data,
const FilePath& fake_base_path)
: fake_base_path_(fake_base_path) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
JSONStringValueSerializer serializer(json_data);
FilePath fake_json_path = fake_base_path.AppendASCII("fake.json");
testing_prefs_.reset(ExtractPrefs(fake_json_path, &serializer));
}
void ExternalTestingExtensionLoader::StartLoading() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
prefs_.reset(testing_prefs_->DeepCopy());
LoadFinished();
}
ExternalTestingExtensionLoader::~ExternalTestingExtensionLoader() {}
const FilePath ExternalTestingExtensionLoader::GetBaseCrxFilePath() {
return fake_base_path_;
}