// 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_; }