| Index: chromeos/ime/component_extension_ime_manager.cc
|
| diff --git a/chromeos/ime/component_extension_ime_manager.cc b/chromeos/ime/component_extension_ime_manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6c7f0685b3eaa725c7c2ee9ea790810edf8471fa
|
| --- /dev/null
|
| +++ b/chromeos/ime/component_extension_ime_manager.cc
|
| @@ -0,0 +1,240 @@
|
| +// Copyright 2013 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 "chromeos/ime/component_extension_ime_manager.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "chromeos/chromeos_switches.h"
|
| +#include "chromeos/ime/extension_ime_util.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +namespace {
|
| +
|
| +// The whitelist for enabling extension based xkb keyboards at login session.
|
| +const char* kLoginLayoutWhitelist[] = {
|
| + "be",
|
| + "br",
|
| + "ca",
|
| + "ca(eng)",
|
| + "ca(multix)",
|
| + "ch",
|
| + "ch(fr)",
|
| + "cz",
|
| + "cz(qwerty)",
|
| + "de",
|
| + "de(neo)",
|
| + "dk",
|
| + "ee",
|
| + "es",
|
| + "es(cat)",
|
| + "fi",
|
| + "fr",
|
| + "gb(dvorak)",
|
| + "gb(extd)",
|
| + "hr",
|
| + "hu",
|
| + "ie",
|
| + "is",
|
| + "it",
|
| + "jp",
|
| + "latam",
|
| + "lt",
|
| + "lv(apostrophe)",
|
| + "mt",
|
| + "no",
|
| + "pl",
|
| + "pt",
|
| + "ro",
|
| + "se",
|
| + "si",
|
| + "tr",
|
| + "us",
|
| + "us(altgr-intl)",
|
| + "us(colemak)",
|
| + "us(dvorak)",
|
| + "us(intl)"
|
| +};
|
| +
|
| +// Gets the input method category according to the given input method id.
|
| +// This is used for sorting a list of input methods.
|
| +int GetInputMethodCategory(const std::string& id) {
|
| + const std::string engine_id =
|
| + chromeos::extension_ime_util::GetComponentIDByInputMethodID(id);
|
| + if (StartsWithASCII(engine_id, "xkb:", true))
|
| + return 0;
|
| + if (StartsWithASCII(engine_id, "vkd_", true))
|
| + return 1;
|
| + if (engine_id.find("-t-i0-") != std::string::npos &&
|
| + !StartsWithASCII(engine_id, "zh-", true)) {
|
| + return 2;
|
| + }
|
| + return 3;
|
| +}
|
| +
|
| +bool InputMethodCompare(const input_method::InputMethodDescriptor& im1,
|
| + const input_method::InputMethodDescriptor& im2) {
|
| + return GetInputMethodCategory(im1.id()) < GetInputMethodCategory(im2.id());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ComponentExtensionEngine::ComponentExtensionEngine() {
|
| +}
|
| +
|
| +ComponentExtensionEngine::~ComponentExtensionEngine() {
|
| +}
|
| +
|
| +ComponentExtensionIME::ComponentExtensionIME() {
|
| +}
|
| +
|
| +ComponentExtensionIME::~ComponentExtensionIME() {
|
| +}
|
| +
|
| +ComponentExtensionIMEManagerDelegate::ComponentExtensionIMEManagerDelegate() {
|
| +}
|
| +
|
| +ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() {
|
| +}
|
| +
|
| +ComponentExtensionIMEManager::ComponentExtensionIMEManager() {
|
| + for (size_t i = 0; i < arraysize(kLoginLayoutWhitelist); ++i) {
|
| + login_layout_set_.insert(kLoginLayoutWhitelist[i]);
|
| + }
|
| +}
|
| +
|
| +ComponentExtensionIMEManager::~ComponentExtensionIMEManager() {
|
| +}
|
| +
|
| +void ComponentExtensionIMEManager::Initialize(
|
| + scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) {
|
| + delegate_ = delegate.Pass();
|
| + std::vector<ComponentExtensionIME> ext_list = delegate_->ListIME();
|
| + for (size_t i = 0; i < ext_list.size(); ++i) {
|
| + ComponentExtensionIME& ext = ext_list[i];
|
| + bool extension_exists = IsWhitelistedExtension(ext.id);
|
| + if (!extension_exists)
|
| + component_extension_imes_[ext.id] = ext;
|
| + for (size_t j = 0; j < ext.engines.size(); ++j) {
|
| + ComponentExtensionEngine& ime = ext.engines[j];
|
| + const std::string input_method_id =
|
| + extension_ime_util::GetComponentInputMethodID(ext.id, ime.engine_id);
|
| + if (extension_exists && !IsWhitelisted(input_method_id))
|
| + component_extension_imes_[ext.id].engines.push_back(ime);
|
| + input_method_id_set_.insert(input_method_id);
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::LoadComponentExtensionIME(
|
| + Profile* profile,
|
| + const std::string& input_method_id) {
|
| + ComponentExtensionIME ime;
|
| + if (FindEngineEntry(input_method_id, &ime)) {
|
| + delegate_->Load(profile, ime.id, ime.manifest, ime.path);
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::UnloadComponentExtensionIME(
|
| + Profile* profile,
|
| + const std::string& input_method_id) {
|
| + ComponentExtensionIME ime;
|
| + if (!FindEngineEntry(input_method_id, &ime))
|
| + return false;
|
| + delegate_->Unload(profile, ime.id, ime.path);
|
| + return true;
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::IsWhitelisted(
|
| + const std::string& input_method_id) {
|
| + return input_method_id_set_.find(input_method_id) !=
|
| + input_method_id_set_.end();
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::IsWhitelistedExtension(
|
| + const std::string& extension_id) {
|
| + return component_extension_imes_.find(extension_id) !=
|
| + component_extension_imes_.end();
|
| +}
|
| +
|
| +input_method::InputMethodDescriptors
|
| + ComponentExtensionIMEManager::GetAllIMEAsInputMethodDescriptor() {
|
| + bool enable_new_korean_ime = CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableNewKoreanIme);
|
| + input_method::InputMethodDescriptors result;
|
| + for (std::map<std::string, ComponentExtensionIME>::const_iterator it =
|
| + component_extension_imes_.begin();
|
| + it != component_extension_imes_.end(); ++it) {
|
| + const ComponentExtensionIME& ext = it->second;
|
| + for (size_t j = 0; j < ext.engines.size(); ++j) {
|
| + const ComponentExtensionEngine& ime = ext.engines[j];
|
| + // Filter out new Korean IME if the experimental flag is OFF.
|
| + if (!enable_new_korean_ime && ime.engine_id == "ko-t-i0-und")
|
| + continue;
|
| + const std::string input_method_id =
|
| + extension_ime_util::GetComponentInputMethodID(
|
| + ext.id, ime.engine_id);
|
| + const std::vector<std::string>& layouts = ime.layouts;
|
| + result.push_back(
|
| + input_method::InputMethodDescriptor(
|
| + input_method_id,
|
| + ime.display_name,
|
| + ime.indicator,
|
| + layouts,
|
| + ime.language_codes,
|
| + // Enables extension based xkb keyboards on login screen.
|
| + extension_ime_util::IsKeyboardLayoutExtension(
|
| + input_method_id) && IsInLoginLayoutWhitelist(layouts),
|
| + ime.options_page_url,
|
| + ime.input_view_url));
|
| + }
|
| + }
|
| + std::stable_sort(result.begin(), result.end(), InputMethodCompare);
|
| + return result;
|
| +}
|
| +
|
| +input_method::InputMethodDescriptors
|
| +ComponentExtensionIMEManager::GetXkbIMEAsInputMethodDescriptor() {
|
| + input_method::InputMethodDescriptors result;
|
| + const input_method::InputMethodDescriptors& descriptors =
|
| + GetAllIMEAsInputMethodDescriptor();
|
| + for (size_t i = 0; i < descriptors.size(); ++i) {
|
| + if (extension_ime_util::IsKeyboardLayoutExtension(descriptors[i].id()))
|
| + result.push_back(descriptors[i]);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::FindEngineEntry(
|
| + const std::string& input_method_id,
|
| + ComponentExtensionIME* out_extension) {
|
| + if (!IsWhitelisted(input_method_id))
|
| + return false;
|
| +
|
| + std::string extension_id =
|
| + extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id);
|
| + std::map<std::string, ComponentExtensionIME>::iterator it =
|
| + component_extension_imes_.find(extension_id);
|
| + if (it == component_extension_imes_.end())
|
| + return false;
|
| +
|
| + if (out_extension)
|
| + *out_extension = it->second;
|
| + return true;
|
| +}
|
| +
|
| +bool ComponentExtensionIMEManager::IsInLoginLayoutWhitelist(
|
| + const std::vector<std::string>& layouts) {
|
| + for (size_t i = 0; i < layouts.size(); ++i) {
|
| + if (login_layout_set_.find(layouts[i]) != login_layout_set_.end())
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|