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 |