This source file includes following definitions.
- GetComponentLoader
- weak_ptr_factory_
- ListIME
- Load
- Unload
- GetManifest
- InitializeAsync
- IsInitialized
- ReadEngineComponent
- ReadExtensionInfo
- ReadComponentExtensionsInfo
- OnReadComponentExtensionsInfo
#include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/base/l10n/l10n_util.h"
namespace chromeos {
namespace {
struct WhitelistedComponentExtensionIME {
const char* id;
const char* path;
} whitelisted_component_extension[] = {
{
"bdgdidmhaijohebebipajioienkglgfo",
"/usr/share/chromeos-assets/input_methods/hangul",
},
#if defined(OFFICIAL_BUILD)
{
"jkghodnilhceideoidjikpgommlajknk",
"/usr/share/chromeos-assets/input_methods/google_xkb",
},
{
"habcdindjejkmepknlhkkloncjcpcnbf",
"/usr/share/chromeos-assets/input_methods/google_keyboards",
},
{
"fpfbhcjppmaeaijcidgiibchfbnhbelj",
"/usr/share/chromeos-assets/input_methods/nacl_mozc",
},
{
"gjaehgfemfahhmlgpdfknkhdnemmolop",
"/usr/share/chromeos-assets/input_methods/input_tools",
},
#else
{
"fgoepimhcoialccpbmpnnblemnepkkao",
"/usr/share/chromeos-assets/input_methods/xkb",
},
{
"jhffeifommiaekmbkkjlpmilogcfdohp",
"/usr/share/chromeos-assets/input_methods/keyboard_layouts",
},
{
"cpgalbafkoofkjmaeonnfijgpfennjjn",
"/usr/share/chromeos-assets/input_methods/pinyin",
},
{
"ekbifjdfhkmdeeajnolmgdlmkllopefi",
"/usr/share/chromeos-assets/input_methods/zhuyin",
},
{
"aeebooiibjahgpgmhkeocbeekccfknbj",
"/usr/share/chromeos-assets/input_methods/cangjie",
},
{
"bbaiamgfapehflhememkfglaehiobjnk",
"/usr/share/chromeos-assets/input_methods/nacl_mozc",
},
#endif
};
extensions::ComponentLoader* GetComponentLoader() {
Profile* profile = ProfileManager::GetActiveUserProfile();
extensions::ExtensionSystem* extension_system =
extensions::ExtensionSystem::Get(profile);
ExtensionService* extension_service = extension_system->extension_service();
return extension_service->component_loader();
}
}
ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl()
: is_initialized_(false),
weak_ptr_factory_(this) {
}
ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() {
}
std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() {
DCHECK(thread_checker_.CalledOnValidThread());
return component_extension_list_;
}
bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id,
const std::string& manifest,
const base::FilePath& file_path) {
DCHECK(thread_checker_.CalledOnValidThread());
Profile* profile = ProfileManager::GetActiveUserProfile();
extensions::ExtensionSystem* extension_system =
extensions::ExtensionSystem::Get(profile);
ExtensionService* extension_service = extension_system->extension_service();
if (extension_service->GetExtensionById(extension_id, false))
return false;
const std::string loaded_extension_id =
GetComponentLoader()->Add(manifest, file_path);
DCHECK_EQ(loaded_extension_id, extension_id);
return true;
}
void ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id,
const base::FilePath& file_path) {
DCHECK(thread_checker_.CalledOnValidThread());
GetComponentLoader()->Remove(extension_id);
}
scoped_ptr<base::DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest(
const base::FilePath& file_path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
std::string error;
scoped_ptr<base::DictionaryValue> manifest(
extension_file_util::LoadManifest(file_path, &error));
if (!manifest.get())
LOG(ERROR) << "Failed at getting manifest";
if (!extension_l10n_util::LocalizeExtension(file_path,
manifest.get(),
&error))
LOG(ERROR) << "Localization failed";
return manifest.Pass();
}
void ComponentExtensionIMEManagerImpl::InitializeAsync(
const base::Closure& callback) {
DCHECK(!is_initialized_);
DCHECK(thread_checker_.CalledOnValidThread());
std::vector<ComponentExtensionIME>* component_extension_ime_list
= new std::vector<ComponentExtensionIME>;
content::BrowserThread::PostTaskAndReply(
content::BrowserThread::FILE,
FROM_HERE,
base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo,
base::Unretained(component_extension_ime_list)),
base::Bind(
&ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(component_extension_ime_list),
callback));
}
bool ComponentExtensionIMEManagerImpl::IsInitialized() {
return is_initialized_;
}
bool ComponentExtensionIMEManagerImpl::ReadEngineComponent(
const ComponentExtensionIME& component_extension,
const base::DictionaryValue& dict,
ComponentExtensionEngine* out) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
DCHECK(out);
std::string type;
if (!dict.GetString(extensions::manifest_keys::kType, &type))
return false;
if (type != "ime")
return false;
if (!dict.GetString(extensions::manifest_keys::kId, &out->engine_id))
return false;
if (!dict.GetString(extensions::manifest_keys::kName, &out->display_name))
return false;
std::set<std::string> languages;
const base::Value* language_value = NULL;
if (dict.Get(extensions::manifest_keys::kLanguage, &language_value)) {
if (language_value->GetType() == base::Value::TYPE_STRING) {
std::string language_str;
language_value->GetAsString(&language_str);
languages.insert(language_str);
} else if (language_value->GetType() == base::Value::TYPE_LIST) {
const base::ListValue* language_list = NULL;
language_value->GetAsList(&language_list);
for (size_t j = 0; j < language_list->GetSize(); ++j) {
std::string language_str;
if (language_list->GetString(j, &language_str))
languages.insert(language_str);
}
}
}
DCHECK(!languages.empty());
out->language_codes.assign(languages.begin(), languages.end());
const base::ListValue* layouts = NULL;
if (!dict.GetList(extensions::manifest_keys::kLayouts, &layouts))
return false;
for (size_t i = 0; i < layouts->GetSize(); ++i) {
std::string buffer;
if (layouts->GetString(i, &buffer))
out->layouts.push_back(buffer);
}
std::string url_string;
if (dict.GetString(extensions::manifest_keys::kInputView,
&url_string)) {
GURL url = extensions::Extension::GetResourceURL(
extensions::Extension::GetBaseURLFromExtensionId(
component_extension.id),
url_string);
if (!url.is_valid())
return false;
out->input_view_url = url;
}
if (dict.GetString(extensions::manifest_keys::kOptionsPage,
&url_string)) {
GURL url = extensions::Extension::GetResourceURL(
extensions::Extension::GetBaseURLFromExtensionId(
component_extension.id),
url_string);
if (!url.is_valid())
return false;
out->options_page_url = url;
} else {
out->options_page_url = component_extension.options_page_url;
}
return true;
}
bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo(
const base::DictionaryValue& manifest,
const std::string& extension_id,
ComponentExtensionIME* out) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
if (!manifest.GetString(extensions::manifest_keys::kDescription,
&out->description))
return false;
std::string url_string;
if (manifest.GetString(extensions::manifest_keys::kOptionsPage,
&url_string)) {
GURL url = extensions::Extension::GetResourceURL(
extensions::Extension::GetBaseURLFromExtensionId(extension_id),
url_string);
if (!url.is_valid())
return false;
out->options_page_url = url;
}
return true;
}
void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo(
std::vector<ComponentExtensionIME>* out_imes) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
DCHECK(out_imes);
for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) {
ComponentExtensionIME component_ime;
component_ime.path = base::FilePath(
whitelisted_component_extension[i].path);
const base::FilePath manifest_path =
component_ime.path.Append("manifest.json");
if (!base::PathExists(component_ime.path) ||
!base::PathExists(manifest_path))
continue;
if (!base::ReadFileToString(manifest_path, &component_ime.manifest))
continue;
scoped_ptr<base::DictionaryValue> manifest =
GetManifest(component_ime.path);
if (!manifest.get())
continue;
if (!ReadExtensionInfo(*manifest.get(),
whitelisted_component_extension[i].id,
&component_ime))
continue;
component_ime.id = whitelisted_component_extension[i].id;
const base::ListValue* component_list;
if (!manifest->GetList(extensions::manifest_keys::kInputComponents,
&component_list))
continue;
for (size_t i = 0; i < component_list->GetSize(); ++i) {
const base::DictionaryValue* dictionary;
if (!component_list->GetDictionary(i, &dictionary))
continue;
ComponentExtensionEngine engine;
ReadEngineComponent(component_ime, *dictionary, &engine);
component_ime.engines.push_back(engine);
}
out_imes->push_back(component_ime);
}
}
void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo(
std::vector<ComponentExtensionIME>* result,
const base::Closure& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(result);
component_extension_list_ = *result;
is_initialized_ = true;
callback.Run();
}
}