| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include <glib.h> | 9 #include <glib.h> |
| 10 | 10 |
| 11 #include "unicode/uloc.h" | 11 #include "unicode/uloc.h" |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/string_split.h" | 16 #include "base/string_split.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/chromeos/cros/cros_library.h" | 19 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 20 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 20 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
| 21 #include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h" |
| 21 #include "chrome/browser/chromeos/input_method/xkeyboard.h" | 22 #include "chrome/browser/chromeos/input_method/xkeyboard.h" |
| 22 #include "chrome/browser/chromeos/language_preferences.h" | 23 #include "chrome/browser/chromeos/language_preferences.h" |
| 23 #include "content/browser/browser_thread.h" | 24 #include "content/browser/browser_thread.h" |
| 24 #include "content/common/notification_observer.h" | 25 #include "content/common/notification_observer.h" |
| 25 #include "content/common/notification_registrar.h" | 26 #include "content/common/notification_registrar.h" |
| 26 #include "content/common/notification_service.h" | 27 #include "content/common/notification_service.h" |
| 28 #include "googleurl/src/gurl.h" |
| 27 | 29 |
| 28 #if !defined(TOUCH_UI) | 30 #if !defined(TOUCH_UI) |
| 29 #include "chrome/browser/chromeos/input_method/candidate_window.h" | 31 #include "chrome/browser/chromeos/input_method/candidate_window.h" |
| 30 #endif | 32 #endif |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; | 36 const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; |
| 35 | 37 |
| 36 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the | 38 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 if (!observers_.size()) { | 117 if (!observers_.size()) { |
| 116 observer->FirstObserverIsAdded(this); | 118 observer->FirstObserverIsAdded(this); |
| 117 } | 119 } |
| 118 observers_.AddObserver(observer); | 120 observers_.AddObserver(observer); |
| 119 } | 121 } |
| 120 | 122 |
| 121 virtual void RemoveObserver(Observer* observer) { | 123 virtual void RemoveObserver(Observer* observer) { |
| 122 observers_.RemoveObserver(observer); | 124 observers_.RemoveObserver(observer); |
| 123 } | 125 } |
| 124 | 126 |
| 127 virtual void AddVirtualKeyboardObserver(VirtualKeyboardObserver* observer) { |
| 128 virtual_keyboard_observers_.AddObserver(observer); |
| 129 } |
| 130 |
| 131 virtual void RemoveVirtualKeyboardObserver( |
| 132 VirtualKeyboardObserver* observer) { |
| 133 virtual_keyboard_observers_.RemoveObserver(observer); |
| 134 } |
| 135 |
| 125 virtual InputMethodDescriptors* GetActiveInputMethods() { | 136 virtual InputMethodDescriptors* GetActiveInputMethods() { |
| 126 chromeos::InputMethodDescriptors* result = | 137 chromeos::InputMethodDescriptors* result = |
| 127 new chromeos::InputMethodDescriptors; | 138 new chromeos::InputMethodDescriptors; |
| 128 // Build the active input method descriptors from the active input | 139 // Build the active input method descriptors from the active input |
| 129 // methods cache |active_input_method_ids_|. | 140 // methods cache |active_input_method_ids_|. |
| 130 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | 141 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
| 131 const std::string& input_method_id = active_input_method_ids_[i]; | 142 const std::string& input_method_id = active_input_method_ids_[i]; |
| 132 const InputMethodDescriptor* descriptor = | 143 const InputMethodDescriptor* descriptor = |
| 133 chromeos::input_method::GetInputMethodDescriptorFromId( | 144 chromeos::input_method::GetInputMethodDescriptorFromId( |
| 134 input_method_id); | 145 input_method_id); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 chromeos::SendHandwritingStroke(input_method_status_connection_, stroke); | 287 chromeos::SendHandwritingStroke(input_method_status_connection_, stroke); |
| 277 } | 288 } |
| 278 | 289 |
| 279 virtual void CancelHandwritingStrokes(int stroke_count) { | 290 virtual void CancelHandwritingStrokes(int stroke_count) { |
| 280 if (!initialized_successfully_) | 291 if (!initialized_successfully_) |
| 281 return; | 292 return; |
| 282 // TODO(yusukes): Rename the libcros function to CancelHandwritingStrokes. | 293 // TODO(yusukes): Rename the libcros function to CancelHandwritingStrokes. |
| 283 chromeos::CancelHandwriting(input_method_status_connection_, stroke_count); | 294 chromeos::CancelHandwriting(input_method_status_connection_, stroke_count); |
| 284 } | 295 } |
| 285 | 296 |
| 297 virtual void RegisterVirtualKeyboard(const GURL& launch_url, |
| 298 const std::set<std::string>& layouts, |
| 299 bool is_system) { |
| 300 if (!initialized_successfully_) |
| 301 return; |
| 302 virtual_keyboard_selector.AddVirtualKeyboard(launch_url, |
| 303 layouts, |
| 304 is_system); |
| 305 } |
| 306 |
| 286 private: | 307 private: |
| 287 // Returns true if the given input method config value is a single | 308 // Returns true if the given input method config value is a single |
| 288 // element string list that contains an input method ID of a keyboard | 309 // element string list that contains an input method ID of a keyboard |
| 289 // layout. | 310 // layout. |
| 290 bool ContainOnlyOneKeyboardLayout( | 311 bool ContainOnlyOneKeyboardLayout( |
| 291 const ImeConfigValue& value) { | 312 const ImeConfigValue& value) { |
| 292 return (value.type == ImeConfigValue::kValueTypeStringList && | 313 return (value.type == ImeConfigValue::kValueTypeStringList && |
| 293 value.string_list_value.size() == 1 && | 314 value.string_list_value.size() == 1 && |
| 294 chromeos::input_method::IsKeyboardLayout( | 315 chromeos::input_method::IsKeyboardLayout( |
| 295 value.string_list_value[0])); | 316 value.string_list_value[0])); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 } | 641 } |
| 621 | 642 |
| 622 // Update input method indicators (e.g. "US", "DV") in Chrome windows. | 643 // Update input method indicators (e.g. "US", "DV") in Chrome windows. |
| 623 // For now, we have to do this every time to keep indicators updated. See | 644 // For now, we have to do this every time to keep indicators updated. See |
| 624 // comments near the FOR_EACH_OBSERVER call in FlushImeConfig() for details. | 645 // comments near the FOR_EACH_OBSERVER call in FlushImeConfig() for details. |
| 625 const size_t num_active_input_methods = GetNumActiveInputMethods(); | 646 const size_t num_active_input_methods = GetNumActiveInputMethods(); |
| 626 FOR_EACH_OBSERVER(Observer, observers_, | 647 FOR_EACH_OBSERVER(Observer, observers_, |
| 627 InputMethodChanged(this, | 648 InputMethodChanged(this, |
| 628 current_input_method_, | 649 current_input_method_, |
| 629 num_active_input_methods)); | 650 num_active_input_methods)); |
| 651 |
| 652 // Update virtual keyboard. |
| 653 #if defined(TOUCH_UI) |
| 654 const input_method::VirtualKeyboard* virtual_keyboard = NULL; |
| 655 std::string virtual_keyboard_layout = ""; |
| 656 |
| 657 static const char kFallbackLayout[] = "us"; |
| 658 std::vector<std::string> layouts_vector |
| 659 = current_input_method_.virtual_keyboard_layouts(); |
| 660 layouts_vector.push_back(kFallbackLayout); |
| 661 |
| 662 for (size_t i = 0; i < layouts_vector.size(); ++i) { |
| 663 virtual_keyboard = |
| 664 virtual_keyboard_selector.SelectVirtualKeyboard(layouts_vector[i]); |
| 665 if (virtual_keyboard) { |
| 666 virtual_keyboard_layout = layouts_vector[i]; |
| 667 if (i == layouts_vector.size() - 1) { |
| 668 // The system virtual keyboard does not support some XKB layouts? or |
| 669 // a third-party input method engine uses a wrong virtual keyboard |
| 670 // layout name? Fallback to the default layout. |
| 671 LOG(ERROR) << "Could not find a virtual keyboard for " |
| 672 << current_input_method_.id |
| 673 << ". Use '" << kFallbackLayout << "' virtual keyboard."; |
| 674 } |
| 675 break; |
| 676 } |
| 677 } |
| 678 // kFallbackLayout should always be supported by one of the system virtual |
| 679 // keyboards. |
| 680 DCHECK(virtual_keyboard); |
| 681 |
| 682 if (virtual_keyboard) { |
| 683 FOR_EACH_OBSERVER(VirtualKeyboardObserver, virtual_keyboard_observers_, |
| 684 VirtualKeyboardChanged(this, |
| 685 *virtual_keyboard, |
| 686 virtual_keyboard_layout)); |
| 687 } |
| 688 #endif // TOUCH_UI |
| 630 } | 689 } |
| 631 | 690 |
| 632 // Changes the current input method from the given input method ID. | 691 // Changes the current input method from the given input method ID. |
| 633 // This function is just a wrapper of ChangeCurrentInputMethod(). | 692 // This function is just a wrapper of ChangeCurrentInputMethod(). |
| 634 void ChangeCurrentInputMethodFromId(const std::string& input_method_id) { | 693 void ChangeCurrentInputMethodFromId(const std::string& input_method_id) { |
| 635 const chromeos::InputMethodDescriptor* descriptor = | 694 const chromeos::InputMethodDescriptor* descriptor = |
| 636 chromeos::input_method::GetInputMethodDescriptorFromId( | 695 chromeos::input_method::GetInputMethodDescriptorFromId( |
| 637 input_method_id); | 696 input_method_id); |
| 638 if (descriptor) { | 697 if (descriptor) { |
| 639 ChangeCurrentInputMethod(*descriptor); | 698 ChangeCurrentInputMethod(*descriptor); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 #if !defined(TOUCH_UI) | 858 #if !defined(TOUCH_UI) |
| 800 candidate_window_controller_.reset(NULL); | 859 candidate_window_controller_.reset(NULL); |
| 801 #endif | 860 #endif |
| 802 } | 861 } |
| 803 } | 862 } |
| 804 | 863 |
| 805 // A reference to the language api, to allow callbacks when the input method | 864 // A reference to the language api, to allow callbacks when the input method |
| 806 // status changes. | 865 // status changes. |
| 807 InputMethodStatusConnection* input_method_status_connection_; | 866 InputMethodStatusConnection* input_method_status_connection_; |
| 808 ObserverList<Observer> observers_; | 867 ObserverList<Observer> observers_; |
| 868 ObserverList<VirtualKeyboardObserver> virtual_keyboard_observers_; |
| 809 | 869 |
| 810 // The input method which was/is selected. | 870 // The input method which was/is selected. |
| 811 InputMethodDescriptor previous_input_method_; | 871 InputMethodDescriptor previous_input_method_; |
| 812 InputMethodDescriptor current_input_method_; | 872 InputMethodDescriptor current_input_method_; |
| 813 | 873 |
| 814 // The input method properties which the current input method uses. The list | 874 // The input method properties which the current input method uses. The list |
| 815 // might be empty when no input method is used. | 875 // might be empty when no input method is used. |
| 816 ImePropertyList current_ime_properties_; | 876 ImePropertyList current_ime_properties_; |
| 817 | 877 |
| 818 typedef std::pair<std::string, std::string> ConfigKeyType; | 878 typedef std::pair<std::string, std::string> ConfigKeyType; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 // loaded and input method status monitoring is started. This value | 915 // loaded and input method status monitoring is started. This value |
| 856 // should be checked where we call libcros functions. | 916 // should be checked where we call libcros functions. |
| 857 bool initialized_successfully_; | 917 bool initialized_successfully_; |
| 858 | 918 |
| 859 // The candidate window. This will be deleted when the APP_TERMINATING | 919 // The candidate window. This will be deleted when the APP_TERMINATING |
| 860 // message is sent. | 920 // message is sent. |
| 861 #if !defined(TOUCH_UI) | 921 #if !defined(TOUCH_UI) |
| 862 scoped_ptr<CandidateWindowController> candidate_window_controller_; | 922 scoped_ptr<CandidateWindowController> candidate_window_controller_; |
| 863 #endif | 923 #endif |
| 864 | 924 |
| 925 // An object which keeps a list of available virtual keyboards. |
| 926 input_method::VirtualKeyboardSelector virtual_keyboard_selector; |
| 927 |
| 865 // The active input method ids cache. | 928 // The active input method ids cache. |
| 866 std::vector<std::string> active_input_method_ids_; | 929 std::vector<std::string> active_input_method_ids_; |
| 867 | 930 |
| 868 DISALLOW_COPY_AND_ASSIGN(InputMethodLibraryImpl); | 931 DISALLOW_COPY_AND_ASSIGN(InputMethodLibraryImpl); |
| 869 }; | 932 }; |
| 870 | 933 |
| 871 InputMethodLibraryImpl::Observer::~Observer() {} | 934 InputMethodLibraryImpl::Observer::~Observer() {} |
| 935 InputMethodLibraryImpl::VirtualKeyboardObserver::~VirtualKeyboardObserver() {} |
| 872 | 936 |
| 873 // The stub implementation of InputMethodLibrary. Used for testing. | 937 // The stub implementation of InputMethodLibrary. Used for testing. |
| 874 class InputMethodLibraryStubImpl : public InputMethodLibrary { | 938 class InputMethodLibraryStubImpl : public InputMethodLibrary { |
| 875 public: | 939 public: |
| 876 InputMethodLibraryStubImpl() | 940 InputMethodLibraryStubImpl() |
| 877 : keyboard_overlay_map_(GetKeyboardOverlayMapForTesting()) { | 941 : keyboard_overlay_map_(GetKeyboardOverlayMapForTesting()) { |
| 878 current_input_method_ = input_method::GetFallbackInputMethodDescriptor(); | 942 current_input_method_ = input_method::GetFallbackInputMethodDescriptor(); |
| 879 } | 943 } |
| 880 | 944 |
| 881 virtual ~InputMethodLibraryStubImpl() {} | 945 virtual ~InputMethodLibraryStubImpl() {} |
| 882 virtual void AddObserver(Observer* observer) {} | 946 virtual void AddObserver(Observer* observer) {} |
| 947 virtual void AddVirtualKeyboardObserver(VirtualKeyboardObserver* observer) {} |
| 883 virtual void RemoveObserver(Observer* observer) {} | 948 virtual void RemoveObserver(Observer* observer) {} |
| 949 virtual void RemoveVirtualKeyboardObserver( |
| 950 VirtualKeyboardObserver* observer) {} |
| 884 | 951 |
| 885 virtual InputMethodDescriptors* GetActiveInputMethods() { | 952 virtual InputMethodDescriptors* GetActiveInputMethods() { |
| 886 return GetInputMethodDescriptorsForTesting(); | 953 return GetInputMethodDescriptorsForTesting(); |
| 887 } | 954 } |
| 888 | 955 |
| 889 | 956 |
| 890 virtual size_t GetNumActiveInputMethods() { | 957 virtual size_t GetNumActiveInputMethods() { |
| 891 scoped_ptr<InputMethodDescriptors> descriptors(GetActiveInputMethods()); | 958 scoped_ptr<InputMethodDescriptors> descriptors(GetActiveInputMethods()); |
| 892 return descriptors->size(); | 959 return descriptors->size(); |
| 893 } | 960 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 | 998 |
| 932 virtual std::string GetKeyboardOverlayId(const std::string& input_method_id) { | 999 virtual std::string GetKeyboardOverlayId(const std::string& input_method_id) { |
| 933 KeyboardOverlayMap::const_iterator iter = | 1000 KeyboardOverlayMap::const_iterator iter = |
| 934 keyboard_overlay_map_->find(input_method_id); | 1001 keyboard_overlay_map_->find(input_method_id); |
| 935 return (iter != keyboard_overlay_map_->end()) ? | 1002 return (iter != keyboard_overlay_map_->end()) ? |
| 936 iter->second : ""; | 1003 iter->second : ""; |
| 937 } | 1004 } |
| 938 | 1005 |
| 939 virtual void SendHandwritingStroke(const HandwritingStroke& stroke) {} | 1006 virtual void SendHandwritingStroke(const HandwritingStroke& stroke) {} |
| 940 virtual void CancelHandwritingStrokes(int stroke_count) {} | 1007 virtual void CancelHandwritingStrokes(int stroke_count) {} |
| 1008 virtual void RegisterVirtualKeyboard(const GURL& launch_url, |
| 1009 const std::set<std::string>& layouts, |
| 1010 bool is_system) {} |
| 941 | 1011 |
| 942 private: | 1012 private: |
| 943 typedef std::map<std::string, std::string> KeyboardOverlayMap; | 1013 typedef std::map<std::string, std::string> KeyboardOverlayMap; |
| 944 | 1014 |
| 945 // Gets input method descriptors for testing. Shouldn't be used for | 1015 // Gets input method descriptors for testing. Shouldn't be used for |
| 946 // production. | 1016 // production. |
| 947 InputMethodDescriptors* GetInputMethodDescriptorsForTesting() { | 1017 InputMethodDescriptors* GetInputMethodDescriptorsForTesting() { |
| 948 InputMethodDescriptors* descriptions = new InputMethodDescriptors; | 1018 InputMethodDescriptors* descriptions = new InputMethodDescriptors; |
| 949 // The list is created from output of gen_engines.py in libcros. | 1019 // The list is created from output of gen_engines.py in libcros. |
| 950 // % SHARE=/build/x86-generic/usr/share python gen_engines.py | 1020 // % SHARE=/build/x86-generic/usr/share python gen_engines.py |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 } | 1264 } |
| 1195 return impl; | 1265 return impl; |
| 1196 } | 1266 } |
| 1197 } | 1267 } |
| 1198 | 1268 |
| 1199 } // namespace chromeos | 1269 } // namespace chromeos |
| 1200 | 1270 |
| 1201 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 1271 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
| 1202 // won't be deleted until it's last InvokeLater is run. | 1272 // won't be deleted until it's last InvokeLater is run. |
| 1203 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); | 1273 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); |
| OLD | NEW |