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