| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/cros/input_method_library.h" | 5 #include "chrome/browser/chromeos/cros/input_method_library.h" |
| 6 | 6 |
| 7 #include <glib.h> | 7 #include <glib.h> |
| 8 #include <signal.h> | 8 #include <signal.h> |
| 9 | 9 |
| 10 #include "unicode/uloc.h" | 10 #include "unicode/uloc.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 : input_method_status_connection_(NULL), | 56 : input_method_status_connection_(NULL), |
| 57 previous_input_method_("", "", "", ""), | 57 previous_input_method_("", "", "", ""), |
| 58 current_input_method_("", "", "", ""), | 58 current_input_method_("", "", "", ""), |
| 59 should_launch_ime_(false), | 59 should_launch_ime_(false), |
| 60 ime_connected_(false), | 60 ime_connected_(false), |
| 61 defer_ime_startup_(false), | 61 defer_ime_startup_(false), |
| 62 enable_auto_ime_shutdown_(true), | 62 enable_auto_ime_shutdown_(true), |
| 63 should_change_input_method_(false), | 63 should_change_input_method_(false), |
| 64 ibus_daemon_process_id_(0), | 64 ibus_daemon_process_id_(0), |
| 65 candidate_window_process_id_(0) { | 65 candidate_window_process_id_(0) { |
| 66 // TODO(yusukes): Using both CreateFallbackInputMethodDescriptors and |
| 67 // chromeos::GetHardwareKeyboardLayoutName doesn't look clean. Probably |
| 68 // we should unify these APIs. |
| 66 scoped_ptr<InputMethodDescriptors> input_method_descriptors( | 69 scoped_ptr<InputMethodDescriptors> input_method_descriptors( |
| 67 CreateFallbackInputMethodDescriptors()); | 70 CreateFallbackInputMethodDescriptors()); |
| 68 current_input_method_ = input_method_descriptors->at(0); | 71 current_input_method_ = input_method_descriptors->at(0); |
| 69 if (CrosLibrary::Get()->EnsureLoaded()) { | 72 if (CrosLibrary::Get()->EnsureLoaded()) { |
| 70 current_input_method_id_ = chromeos::GetHardwareKeyboardLayoutName(); | 73 current_input_method_id_ = chromeos::GetHardwareKeyboardLayoutName(); |
| 71 } | 74 } |
| 72 // Observe APP_EXITING to stop input method processes gracefully. | 75 // Observe APP_EXITING to stop input method processes gracefully. |
| 73 // Note that even if we fail to stop input method processes from | 76 // Note that even if we fail to stop input method processes from |
| 74 // Chrome in case of a sudden crash, we have a way to do it from an | 77 // Chrome in case of a sudden crash, we have a way to do it from an |
| 75 // upstart script. See crosbug.com/6515 and crosbug.com/6995 for | 78 // upstart script. See crosbug.com/6515 and crosbug.com/6995 for |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 scoped_ptr<InputMethodDescriptors> active_input_method_descriptors( | 144 scoped_ptr<InputMethodDescriptors> active_input_method_descriptors( |
| 142 GetActiveInputMethods()); | 145 GetActiveInputMethods()); |
| 143 for (size_t i = 0; i < active_input_method_descriptors->size(); ++i) { | 146 for (size_t i = 0; i < active_input_method_descriptors->size(); ++i) { |
| 144 if (active_input_method_descriptors->at(i).id == input_method_id) { | 147 if (active_input_method_descriptors->at(i).id == input_method_id) { |
| 145 return true; | 148 return true; |
| 146 } | 149 } |
| 147 } | 150 } |
| 148 return false; | 151 return false; |
| 149 } | 152 } |
| 150 | 153 |
| 151 bool GetImeConfig(const char* section, const char* config_name, | 154 bool GetImeConfig(const std::string& section, const std::string& config_name, |
| 152 ImeConfigValue* out_value) { | 155 ImeConfigValue* out_value) { |
| 153 bool success = false; | 156 bool success = false; |
| 154 if (EnsureLoadedAndStarted()) { | 157 if (EnsureLoadedAndStarted()) { |
| 155 success = chromeos::GetImeConfig(input_method_status_connection_, | 158 success = chromeos::GetImeConfig(input_method_status_connection_, |
| 156 section, config_name, out_value); | 159 section.c_str(), |
| 160 config_name.c_str(), |
| 161 out_value); |
| 157 } | 162 } |
| 158 return success; | 163 return success; |
| 159 } | 164 } |
| 160 | 165 |
| 161 bool SetImeConfig(const char* section, const char* config_name, | 166 bool SetImeConfig(const std::string& section, const std::string& config_name, |
| 162 const ImeConfigValue& value) { | 167 const ImeConfigValue& value) { |
| 163 MaybeStartOrStopInputMethodProcesses(section, config_name, value); | 168 // Before calling FlushImeConfig(), start input method process if necessary. |
| 169 MaybeStartInputMethodProcesses(section, config_name, value); |
| 164 | 170 |
| 165 const ConfigKeyType key = std::make_pair(section, config_name); | 171 const ConfigKeyType key = std::make_pair(section, config_name); |
| 166 current_config_values_[key] = value; | 172 current_config_values_[key] = value; |
| 167 if (ime_connected_) { | 173 if (ime_connected_) { |
| 168 pending_config_requests_[key] = value; | 174 pending_config_requests_[key] = value; |
| 169 FlushImeConfig(); | 175 FlushImeConfig(); |
| 170 } | 176 } |
| 177 |
| 178 // Stop input method process if necessary. |
| 179 MaybeStopInputMethodProcesses(section, config_name, value); |
| 171 return pending_config_requests_.empty(); | 180 return pending_config_requests_.empty(); |
| 172 } | 181 } |
| 173 | 182 |
| 174 virtual const InputMethodDescriptor& previous_input_method() const { | 183 virtual const InputMethodDescriptor& previous_input_method() const { |
| 175 return previous_input_method_; | 184 return previous_input_method_; |
| 176 } | 185 } |
| 177 virtual const InputMethodDescriptor& current_input_method() const { | 186 virtual const InputMethodDescriptor& current_input_method() const { |
| 178 return current_input_method_; | 187 return current_input_method_; |
| 179 } | 188 } |
| 180 | 189 |
| 181 virtual const ImePropertyList& current_ime_properties() const { | 190 virtual const ImePropertyList& current_ime_properties() const { |
| 182 return current_ime_properties_; | 191 return current_ime_properties_; |
| 183 } | 192 } |
| 184 | 193 |
| 185 private: | 194 private: |
| 186 // Starts or stops the input method processes based on the current state. | 195 // Starts input method processes based on the |defer_ime_startup_| flag and |
| 187 void MaybeStartOrStopInputMethodProcesses( | 196 // input method configuration being updated. |section| is a section name of |
| 188 const char* section, | 197 // the input method configuration (e.g. "general", "general/hotkey"). |
| 189 const char* config_name, | 198 // |config_name| is a name of the configuration (e.g. "preload_engines", |
| 190 const ImeConfigValue& value) { | 199 // "previous_engine"). |value| is the configuration value to be set. |
| 191 if (!strcmp(language_prefs::kGeneralSectionName, section) && | 200 void MaybeStartInputMethodProcesses(const std::string& section, |
| 192 !strcmp(language_prefs::kPreloadEnginesConfigName, config_name)) { | 201 const std::string& config_name, |
| 202 const ImeConfigValue& value) { |
| 203 if (section == language_prefs::kGeneralSectionName && |
| 204 config_name == language_prefs::kPreloadEnginesConfigName) { |
| 193 if (EnsureLoadedAndStarted()) { | 205 if (EnsureLoadedAndStarted()) { |
| 194 // If there are no input methods other than one for the hardware | 206 const std::string hardware_layout_name = |
| 195 // keyboard, we'll stop the input method processes. | 207 chromeos::GetHardwareKeyboardLayoutName(); // e.g. "xkb:us::eng" |
| 196 if (value.type == ImeConfigValue::kValueTypeStringList && | 208 if (!(value.type == ImeConfigValue::kValueTypeStringList && |
| 197 value.string_list_value.size() == 1 && | 209 value.string_list_value.size() == 1 && |
| 198 value.string_list_value[0] == | 210 value.string_list_value[0] == hardware_layout_name) && |
| 199 chromeos::GetHardwareKeyboardLayoutName()) { | 211 !defer_ime_startup_) { |
| 200 if (enable_auto_ime_shutdown_) | 212 // If there are no input methods other than one for the hardware |
| 201 StopInputMethodProcesses(); | 213 // keyboard, we don't start the input method processes. |
| 202 } else if (!defer_ime_startup_) { | 214 // When |defer_ime_startup_| is true, we don't start it either. |
| 203 StartInputMethodProcesses(); | 215 StartInputMethodProcesses(); |
| 204 } | 216 } |
| 205 chromeos::SetActiveInputMethods(input_method_status_connection_, value); | 217 chromeos::SetActiveInputMethods(input_method_status_connection_, value); |
| 206 } | 218 } |
| 219 } |
| 220 } |
| 221 |
| 222 // Stops input method processes based on the |enable_auto_ime_shutdown_| flag |
| 223 // and input method configuration being updated. |
| 224 // See also: MaybeStartInputMethodProcesses(). |
| 225 void MaybeStopInputMethodProcesses(const std::string& section, |
| 226 const std::string& config_name, |
| 227 const ImeConfigValue& value) { |
| 228 if (section == language_prefs::kGeneralSectionName && |
| 229 config_name == language_prefs::kPreloadEnginesConfigName) { |
| 230 if (EnsureLoadedAndStarted()) { |
| 231 const std::string hardware_layout_name = |
| 232 chromeos::GetHardwareKeyboardLayoutName(); // e.g. "xkb:us::eng" |
| 233 if (value.type == ImeConfigValue::kValueTypeStringList && |
| 234 value.string_list_value.size() == 1 && |
| 235 value.string_list_value[0] == hardware_layout_name && |
| 236 enable_auto_ime_shutdown_) { |
| 237 // If there are no input methods other than one for the hardware |
| 238 // keyboard, and |enable_auto_ime_shutdown_| is true, we'll stop the |
| 239 // input method processes. |
| 240 StopInputMethodProcesses(); |
| 241 } |
| 242 chromeos::SetActiveInputMethods(input_method_status_connection_, value); |
| 243 } |
| 207 } | 244 } |
| 208 } | 245 } |
| 209 | 246 |
| 210 // Changes the current input method to |input_method_id|. If the id is not in | 247 // Changes the current input method to |input_method_id|. If the id is not in |
| 211 // the preload_engine list, this function changes the current method to the | 248 // the preload_engine list, this function changes the current method to the |
| 212 // first preloaded engine. Returns true if the current engine is switched to | 249 // first preloaded engine. Returns true if the current engine is switched to |
| 213 // |input_method_id| or the first one. | 250 // |input_method_id| or the first one. |
| 214 bool ChangeInputMethodInternal(const std::string& input_method_id) { | 251 bool ChangeInputMethodInternal(const std::string& input_method_id) { |
| 215 DCHECK(EnsureLoadedAndStarted()); | 252 DCHECK(EnsureLoadedAndStarted()); |
| 216 std::string input_method_id_to_switch = input_method_id; | 253 std::string input_method_id_to_switch = input_method_id; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 current_input_method_, | 334 current_input_method_, |
| 298 num_active_input_methods)); | 335 num_active_input_methods)); |
| 299 } | 336 } |
| 300 } | 337 } |
| 301 | 338 |
| 302 static void InputMethodChangedHandler( | 339 static void InputMethodChangedHandler( |
| 303 void* object, | 340 void* object, |
| 304 const chromeos::InputMethodDescriptor& current_input_method) { | 341 const chromeos::InputMethodDescriptor& current_input_method) { |
| 305 // The handler is called when the input method method change is | 342 // The handler is called when the input method method change is |
| 306 // notified via a DBus connection. Since the DBus notificatiosn are | 343 // notified via a DBus connection. Since the DBus notificatiosn are |
| 307 // handled in the UI thread, we can assume that this functionalways | 344 // handled in the UI thread, we can assume that this function always |
| 308 // runs on the UI thread, but just in case. | 345 // runs on the UI thread, but just in case. |
| 309 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 346 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 310 LOG(ERROR) << "Not on UI thread"; | 347 LOG(ERROR) << "Not on UI thread"; |
| 311 return; | 348 return; |
| 312 } | 349 } |
| 313 | 350 |
| 314 InputMethodLibraryImpl* input_method_library = | 351 InputMethodLibraryImpl* input_method_library = |
| 315 static_cast<InputMethodLibraryImpl*>(object); | 352 static_cast<InputMethodLibraryImpl*>(object); |
| 316 input_method_library->ChangeCurrentInputMethod(current_input_method); | 353 input_method_library->ChangeCurrentInputMethod(current_input_method); |
| 317 } | 354 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 // This is used to register this object to APP_EXITING notification. | 616 // This is used to register this object to APP_EXITING notification. |
| 580 NotificationRegistrar notification_registrar_; | 617 NotificationRegistrar notification_registrar_; |
| 581 | 618 |
| 582 // True if we should launch the input method processes. | 619 // True if we should launch the input method processes. |
| 583 bool should_launch_ime_; | 620 bool should_launch_ime_; |
| 584 // True if the connection to the IBus daemon is alive. | 621 // True if the connection to the IBus daemon is alive. |
| 585 bool ime_connected_; | 622 bool ime_connected_; |
| 586 // If true, we'll defer the startup until a non-default method is | 623 // If true, we'll defer the startup until a non-default method is |
| 587 // activated. | 624 // activated. |
| 588 bool defer_ime_startup_; | 625 bool defer_ime_startup_; |
| 626 // True if we should stop input method processes when there are no input |
| 627 // methods other than one for the hardware keyboard. |
| 589 bool enable_auto_ime_shutdown_; | 628 bool enable_auto_ime_shutdown_; |
| 590 // The ID of the current input method (ex. "mozc"). | 629 // The ID of the current input method (ex. "mozc"). |
| 591 std::string current_input_method_id_; | 630 std::string current_input_method_id_; |
| 592 // True if we should change the input method once the queue of the | 631 // True if we should change the input method once the queue of the |
| 593 // pending config requests becomes empty. | 632 // pending config requests becomes empty. |
| 594 bool should_change_input_method_; | 633 bool should_change_input_method_; |
| 595 | 634 |
| 596 // The process id of the IBus daemon. 0 if it's not running. The process | 635 // The process id of the IBus daemon. 0 if it's not running. The process |
| 597 // ID 0 is not used in Linux, hence it's safe to use 0 for this purpose. | 636 // ID 0 is not used in Linux, hence it's safe to use 0 for this purpose. |
| 598 int ibus_daemon_process_id_; | 637 int ibus_daemon_process_id_; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 return CreateRealisticInputMethodDescriptors(); | 669 return CreateRealisticInputMethodDescriptors(); |
| 631 } | 670 } |
| 632 | 671 |
| 633 void ChangeInputMethod(const std::string& input_method_id) {} | 672 void ChangeInputMethod(const std::string& input_method_id) {} |
| 634 void SetImePropertyActivated(const std::string& key, bool activated) {} | 673 void SetImePropertyActivated(const std::string& key, bool activated) {} |
| 635 | 674 |
| 636 bool InputMethodIsActivated(const std::string& input_method_id) { | 675 bool InputMethodIsActivated(const std::string& input_method_id) { |
| 637 return true; | 676 return true; |
| 638 } | 677 } |
| 639 | 678 |
| 640 bool GetImeConfig(const char* section, | 679 bool GetImeConfig(const std::string& section, |
| 641 const char* config_name, | 680 const std::string& config_name, |
| 642 ImeConfigValue* out_value) { | 681 ImeConfigValue* out_value) { |
| 643 return false; | 682 return false; |
| 644 } | 683 } |
| 645 | 684 |
| 646 bool SetImeConfig(const char* section, | 685 bool SetImeConfig(const std::string& section, |
| 647 const char* config_name, | 686 const std::string& config_name, |
| 648 const ImeConfigValue& value) { | 687 const ImeConfigValue& value) { |
| 649 return false; | 688 return false; |
| 650 } | 689 } |
| 651 | 690 |
| 652 virtual const InputMethodDescriptor& previous_input_method() const { | 691 virtual const InputMethodDescriptor& previous_input_method() const { |
| 653 return previous_input_method_; | 692 return previous_input_method_; |
| 654 } | 693 } |
| 655 | 694 |
| 656 virtual const InputMethodDescriptor& current_input_method() const { | 695 virtual const InputMethodDescriptor& current_input_method() const { |
| 657 return current_input_method_; | 696 return current_input_method_; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 return new InputMethodLibraryStubImpl(); | 847 return new InputMethodLibraryStubImpl(); |
| 809 else | 848 else |
| 810 return new InputMethodLibraryImpl(); | 849 return new InputMethodLibraryImpl(); |
| 811 } | 850 } |
| 812 | 851 |
| 813 } // namespace chromeos | 852 } // namespace chromeos |
| 814 | 853 |
| 815 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 854 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
| 816 // won't be deleted until it's last InvokeLater is run. | 855 // won't be deleted until it's last InvokeLater is run. |
| 817 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); | 856 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); |
| OLD | NEW |