Commit 54ccafa6 authored by zork@chromium.org's avatar zork@chromium.org

Start the IME Daemon when adding an extension IME

Cleanup the connection member of the engine object when destructing.
Properly unregister IMEs when unloading extensions.

BUG=chromium-os:21357,21514,21355
TEST=See bugs


Review URL: http://codereview.chromium.org/8761018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113284 0039d316-1c4b-4281-b951-d872f2087c98
parent dbf036fc
......@@ -81,6 +81,10 @@ class IBusEngineControllerImpl : public IBusEngineController {
}
~IBusEngineControllerImpl() {
for (std::set<IBusChromeOSEngine*>::iterator ix = engine_instances_.begin();
ix != engine_instances_.end(); ++ix) {
(*ix)->connection = NULL;
}
if (preedit_text_) {
g_object_unref(preedit_text_);
preedit_text_ = NULL;
......@@ -710,49 +714,61 @@ class IBusEngineControllerImpl : public IBusEngineController {
GDBusMethodInvocation* key_data) {
VLOG(1) << "OnProcessKeyEvent";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnKeyEvent(
!(modifiers & IBUS_RELEASE_MASK),
keyval, keycode,
modifiers & IBUS_MOD1_MASK,
modifiers & IBUS_CONTROL_MASK,
modifiers & IBUS_SHIFT_MASK,
reinterpret_cast<KeyEventHandle*>(key_data));
if (engine->connection) {
engine->connection->observer_->OnKeyEvent(
!(modifiers & IBUS_RELEASE_MASK),
keyval, keycode,
modifiers & IBUS_MOD1_MASK,
modifiers & IBUS_CONTROL_MASK,
modifiers & IBUS_SHIFT_MASK,
reinterpret_cast<KeyEventHandle*>(key_data));
}
}
static void OnReset(IBusEngine* ibus_engine) {
VLOG(1) << "OnReset";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnReset();
if (engine->connection) {
engine->connection->observer_->OnReset();
}
}
static void OnEnable(IBusEngine* ibus_engine) {
VLOG(1) << "OnEnable";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->active_engine_ = engine;
engine->connection->observer_->OnEnable();
engine->connection->SetProperties();
if (engine->connection) {
engine->connection->active_engine_ = engine;
engine->connection->observer_->OnEnable();
engine->connection->SetProperties();
}
}
static void OnDisable(IBusEngine* ibus_engine) {
VLOG(1) << "OnDisable";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnDisable();
if (engine->connection->active_engine_ == engine) {
engine->connection->active_engine_ = NULL;
if (engine->connection) {
engine->connection->observer_->OnDisable();
if (engine->connection->active_engine_ == engine) {
engine->connection->active_engine_ = NULL;
}
}
}
static void OnFocusIn(IBusEngine* ibus_engine) {
VLOG(1) << "OnFocusIn";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnFocusIn();
engine->connection->SetProperties();
if (engine->connection) {
engine->connection->observer_->OnFocusIn();
engine->connection->SetProperties();
}
}
static void OnFocusOut(IBusEngine* ibus_engine) {
VLOG(1) << "OnFocusOut";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnFocusOut();
if (engine->connection) {
engine->connection->observer_->OnFocusOut();
}
}
static void OnPageUp(IBusEngine* ibus_engine) {
......@@ -775,25 +791,29 @@ class IBusEngineControllerImpl : public IBusEngineController {
const gchar *prop_name, guint prop_state) {
VLOG(1) << "OnPropertyActivate";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
engine->connection->observer_->OnPropertyActivate(prop_name, prop_state);
if (engine->connection) {
engine->connection->observer_->OnPropertyActivate(prop_name, prop_state);
}
}
static void OnCandidateClicked(IBusEngine* ibus_engine, guint index,
guint button, guint state) {
VLOG(1) << "OnCandidateClicked";
IBusChromeOSEngine* engine = IBUS_CHROMEOS_ENGINE(ibus_engine);
int pressed_button = 0;
if (button & IBUS_BUTTON1_MASK) {
pressed_button |= MOUSE_BUTTON_1_MASK;
}
if (button & IBUS_BUTTON2_MASK) {
pressed_button |= MOUSE_BUTTON_2_MASK;
}
if (button & IBUS_BUTTON3_MASK) {
pressed_button |= MOUSE_BUTTON_3_MASK;
if (engine->connection) {
int pressed_button = 0;
if (button & IBUS_BUTTON1_MASK) {
pressed_button |= MOUSE_BUTTON_1_MASK;
}
if (button & IBUS_BUTTON2_MASK) {
pressed_button |= MOUSE_BUTTON_2_MASK;
}
if (button & IBUS_BUTTON3_MASK) {
pressed_button |= MOUSE_BUTTON_3_MASK;
}
engine->connection->observer_->OnCandidateClicked(index, pressed_button,
state);
}
engine->connection->observer_->OnCandidateClicked(index, pressed_button,
state);
}
static GObject* EngineConstructor(GType type, guint n_construct_params,
......@@ -805,6 +825,8 @@ class IBusEngineControllerImpl : public IBusEngineController {
ConnectionMap::iterator connection = g_connections_->find(name);
if (connection == g_connections_->end()) {
LOG(ERROR) << "Connection never created: " << name;
engine->connection = NULL;
engine->table = NULL;
return (GObject *) engine;
}
......
......@@ -384,8 +384,11 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
FlushImeConfig();
}
// Stop input method process if necessary.
MaybeStopInputMethodDaemon(section, config_name, value);
if (section == language_prefs::kGeneralSectionName &&
config_name == language_prefs::kPreloadEnginesConfigName) {
// Stop input method process if necessary.
MaybeStopInputMethodDaemon();
}
// Change the current keyboard layout if necessary.
MaybeChangeCurrentKeyboardLayout(section, config_name, value);
return pending_config_requests_.empty();
......@@ -403,6 +406,9 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
active_input_method_ids_.push_back(id);
// TODO(yusukes): Call UpdateInputMethodSpecificHotkeys() here once IME
// extension supports hotkeys.
// Ensure that the input method daemon is running.
StartInputMethodDaemon();
}
virtual void RemoveActiveIme(const std::string& id) {
......@@ -416,6 +422,9 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
extra_input_method_ids_.erase(id);
// TODO(yusukes): Call UpdateInputMethodSpecificHotkeys() here once IME
// extension supports hotkeys.
// Stop the IME daemon if needed.
MaybeStopInputMethodDaemon();
}
virtual bool GetExtraDescriptor(const std::string& id,
......@@ -588,12 +597,9 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
// Returns true if the given input method config value is a string list
// that only contains an input method ID of a keyboard layout.
bool ContainOnlyKeyboardLayout(const ImeConfigValue& value) {
if (value.type != ImeConfigValue::kValueTypeStringList) {
return false;
}
for (size_t i = 0; i < value.string_list_value.size(); ++i) {
if (!InputMethodUtil::IsKeyboardLayout(value.string_list_value[i])) {
bool ContainOnlyKeyboardLayout(const std::vector<std::string>& value) {
for (size_t i = 0; i < value.size(); ++i) {
if (!InputMethodUtil::IsKeyboardLayout(value[i])) {
return false;
}
}
......@@ -615,7 +621,8 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
// If there is only one input method which is a keyboard layout,
// we don't start the input method processes. When
// |defer_ime_startup_| is true, we don't start it either.
if (ContainOnlyKeyboardLayout(value) || defer_ime_startup_) {
if (ContainOnlyKeyboardLayout(value.string_list_value) ||
defer_ime_startup_) {
// Do not start the input method daemon.
return;
}
......@@ -659,21 +666,17 @@ class InputMethodManagerImpl : public HotkeyManager::Observer,
// Stops input method daemon based on the |enable_auto_ime_shutdown_| flag
// and input method configuration being updated.
// See also: MaybeStartInputMethodDaemon().
void MaybeStopInputMethodDaemon(const std::string& section,
const std::string& config_name,
const ImeConfigValue& value) {
void MaybeStopInputMethodDaemon() {
// If there is only one input method which is a keyboard layout,
// and |enable_auto_ime_shutdown_| is true, we'll stop the input
// method daemon.
if (section == language_prefs::kGeneralSectionName &&
config_name == language_prefs::kPreloadEnginesConfigName &&
ContainOnlyKeyboardLayout(value) &&
if (ContainOnlyKeyboardLayout(active_input_method_ids_) &&
enable_auto_ime_shutdown_) {
if (StopInputMethodDaemon()) {
// The process is killed. Change the current keyboard layout.
// We shouldn't use SetCurrentKeyboardLayoutByName() here. See
// comments at ChangeCurrentInputMethod() for details.
ChangeCurrentInputMethodFromId(value.string_list_value[0]);
ChangeCurrentInputMethodFromId(active_input_method_ids_[0]);
}
}
}
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/extensions/extension_input_ime_api.h"
#include "base/json/json_writer.h"
#include "base/stl_util.h"
#include "base/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/chromeos/input_method/input_method_engine.h"
......@@ -423,6 +424,29 @@ bool ExtensionInputImeEventRouter::RegisterIme(
return true;
}
void ExtensionInputImeEventRouter::UnregisterAllImes(
Profile* profile, const std::string& extension_id) {
std::map<std::string,
std::map<std::string,
chromeos::InputMethodEngine*> >::iterator engine_map =
engines_.find(extension_id);
if (engine_map != engines_.end()) {
STLDeleteContainerPairSecondPointers(engine_map->second.begin(),
engine_map->second.end());
engines_.erase(engine_map);
}
std::map<std::string,
std::map<std::string,
chromeos::ImeObserver*> >::iterator observer_list =
observers_.find(extension_id);
if (observer_list != observers_.end()) {
STLDeleteContainerPairSecondPointers(observer_list->second.begin(),
observer_list->second.end());
observers_.erase(observer_list);
}
}
#endif
chromeos::InputMethodEngine* ExtensionInputImeEventRouter::GetEngine(
......
......@@ -32,6 +32,7 @@ class ExtensionInputImeEventRouter {
bool RegisterIme(Profile* profile,
const std::string& extension_id,
const Extension::InputComponentInfo& component);
void UnregisterAllImes(Profile* profile, const std::string& extension_id);
chromeos::InputMethodEngine* GetEngine(const std::string& extension_id,
const std::string& engine_id);
chromeos::InputMethodEngine* GetActiveEngine(const std::string& extension_id);
......
......@@ -1060,6 +1060,11 @@ void ExtensionService::NotifyExtensionUnloaded(
profile_->GetFileSystemContext()->path_manager()->external_provider()->
RevokeAccessForExtension(extension->id());
}
if (extension->input_components().size() > 0) {
ExtensionInputImeEventRouter::GetInstance()->UnregisterAllImes(
profile_, extension->id());
}
#endif
UpdateActiveExtensionsInCrashReporter();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment