| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS 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 <base/logging.h> | 5 #include <base/logging.h> |
| 6 #include <base/scoped_ptr.h> | 6 #include <base/scoped_ptr.h> |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <glib-object.h> | 8 #include <glib-object.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 | 10 |
| 11 #include <iostream> // NOLINT | 11 #include <iostream> // NOLINT |
| 12 | 12 |
| 13 #include "chromeos_cros_api.h" // NOLINT | 13 #include "chromeos_cros_api.h" // NOLINT |
| 14 #include "chromeos_language.h" | 14 #include "chromeos_language.h" |
| 15 #include "monitor_utils.h" //NOLINT | 15 #include "monitor_utils.h" //NOLINT |
| 16 | 16 |
| 17 // \file This is a simple console application which checks whether the cros | 17 // \file This is a simple console application which checks whether the cros |
| 18 // library (chromeos_language.cc) can monitor IME/XKB status changes or not. | 18 // library (chromeos_language.cc) can monitor IME/XKB status changes or not. |
| 19 | 19 |
| 20 // How to use this tool: | 20 // How to use this tool: |
| 21 // 1. Set up your IBus daemon using ibus-setup command. Add at least one IME. | 21 // 1. Set up your IBus daemon using ibus-setup command. Add at least one IME. |
| 22 // 2. Start the candidate_window for ChromeOS. | 22 // 2. Start the candidate_window for ChromeOS. |
| 23 // 3. Start this tool ***in your gnome-terminal***. You need to have X desktop. | 23 // 3. Start this tool ***in your gnome-terminal***. You need to have X desktop. |
| 24 // 4. Verify that all IME languages and XKB layouts are displayed. | 24 // 4. Verify that all IME languages and XKB layouts are displayed. |
| 25 // 5. Verify that the last IME is deactivated and then reactivated. | 25 // 5. Verify that the last IME is deactivated and then reactivated. |
| 26 // 6. Focus another X application, then focus back the gnome-terminal in order | 26 // 6. Focus another X application, then focus back the gnome-terminal in order |
| 27 // to make candidate_window send "FocusIn" signal to this process. Please | 27 // to make candidate_window send "FocusIn" signal to this process. Please |
| 28 // note that Callback::Run() is called upon "FocusIn" and "StateChanged" | 28 // note that Callback::UpdateCurrentLanguage() is called upon "FocusIn" and |
| 29 // signals from candidate_window. | 29 // "StateChanged" signals from candidate_window. Likewise, |
| 30 // Callback::RegisterProperties() is for "RegisterProperties" signal and |
| 31 // Callback::UpdateProperty() is for "UpdateProperty" signal from the window. |
| 30 // 7. Verify that this tool automatically exits in a second or so. | 32 // 7. Verify that this tool automatically exits in a second or so. |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 const size_t kTestCount = 5; | 36 const size_t kTestCount = 5; |
| 35 chromeos::LanguageStatusConnection* global_connection = NULL; | 37 chromeos::LanguageStatusConnection* global_connection = NULL; |
| 36 | 38 |
| 39 void DumpProperties(const chromeos::ImePropertyList& prop_list) { |
| 40 for (size_t i = 0; i < prop_list.size(); ++i) { |
| 41 DLOG(INFO) << "Property #" << i << ": " << prop_list[i].ToString(); |
| 42 } |
| 43 } |
| 44 |
| 37 } // namespace | 45 } // namespace |
| 38 | 46 |
| 39 // Callback is an example object which can be passed to MonitorLanguageStatus. | 47 // Callback is an example object which can be passed to MonitorLanguageStatus. |
| 40 class Callback { | 48 class Callback { |
| 41 public: | 49 public: |
| 42 // You can store whatever state is needed in the function object. | 50 // You can store whatever state is needed in the function object. |
| 43 explicit Callback(GMainLoop* loop) | 51 explicit Callback(GMainLoop* loop) |
| 44 : count_(0), loop_(loop) { | 52 : count_(0), loop_(loop) { |
| 45 } | 53 } |
| 46 | 54 |
| 47 static void Run(void* object, const chromeos::InputLanguage& language) { | 55 static void UpdateCurrentLanguage(void* object, |
| 56 const chromeos::InputLanguage& language) { |
| 48 Callback* self = static_cast<Callback*>(object); | 57 Callback* self = static_cast<Callback*>(object); |
| 49 | 58 |
| 50 ++self->count_; | 59 ++self->count_; |
| 51 if (self->count_ == kTestCount) { | 60 if (self->count_ == kTestCount) { |
| 52 std::cout << "*** Done ***" << std::endl; | 61 LOG(INFO) << "*** Done ***"; |
| 53 ::g_main_loop_quit(self->loop_); | 62 ::g_main_loop_quit(self->loop_); |
| 54 } else { | 63 } else { |
| 55 // Change the current IME engine or XKB layout by calling | 64 // Change the current IME engine or XKB layout by calling |
| 56 // ChromeOSChangeLanguage() function in libcros. | 65 // ChromeOSChangeLanguage() function in libcros. |
| 57 // | 66 // |
| 58 // 1. Calls the ChromeOSChangeLanguage() function. | 67 // 1. Calls the ChromeOSChangeLanguage() function. |
| 59 // 2. The function calls "SetEngine" method (if language->category is | 68 // 2. The function calls "SetEngine" method (if language->category is |
| 60 // IME) or "Disable" method (if the category is XKB) in ibus-daemon. | 69 // IME) or "Disable" method (if the category is XKB) in ibus-daemon. |
| 61 // 3. ibus-daemon changes its state and calls "StateChanged" method in | 70 // 3. ibus-daemon changes its state and calls "StateChanged" method in |
| 62 // candidate_window. | 71 // candidate_window. |
| 63 // 4. candidate_window sends "StateChanged" signal to this process. | 72 // 4. candidate_window sends "StateChanged" signal to this process. |
| 64 // 5. Since |self| is registered as a monitor function, libcros calls | 73 // 5. Since |self| is registered as a monitor function, libcros calls |
| 65 // Callback::Run() function again. | 74 // Callback::UpdateCurrentLanguage() function again. |
| 66 // | 75 // |
| 67 // As a result, "SetEngine" method and "Disable" method in ibus-daemon | 76 // As a result, "SetEngine" method and "Disable" method in ibus-daemon |
| 68 // are called in turn rapidly. | 77 // are called in turn rapidly. |
| 69 if (language.category == chromeos::LANGUAGE_CATEGORY_XKB) { | 78 if (language.category == chromeos::LANGUAGE_CATEGORY_XKB) { |
| 70 // This triggers the Run() function to be called again | 79 // This triggers the UpdateCurrentLanguage() function to be called again |
| 71 // (see the comment above). | 80 // (see the comment above). |
| 72 chromeos::ChangeLanguage(global_connection, | 81 chromeos::ChangeLanguage(global_connection, |
| 73 chromeos::LANGUAGE_CATEGORY_IME, | 82 chromeos::LANGUAGE_CATEGORY_IME, |
| 74 self->ime_id().c_str()); | 83 self->ime_id().c_str()); |
| 75 } else { | 84 } else { |
| 76 // Ditto. | 85 // Ditto. |
| 77 chromeos::ChangeLanguage(global_connection, | 86 chromeos::ChangeLanguage(global_connection, |
| 78 chromeos::LANGUAGE_CATEGORY_XKB, | 87 chromeos::LANGUAGE_CATEGORY_XKB, |
| 79 self->xkb_id().c_str()); | 88 self->xkb_id().c_str()); |
| 80 } | 89 } |
| 81 } | 90 } |
| 82 } | 91 } |
| 83 | 92 |
| 93 static void RegisterProperties(void* object, |
| 94 const chromeos::ImePropertyList& prop_list) { |
| 95 DLOG(INFO) << "In callback function for the RegisterProperties signal"; |
| 96 DumpProperties(prop_list); |
| 97 } |
| 98 |
| 99 static void UpdateProperty(void* object, |
| 100 const chromeos::ImePropertyList& prop_list) { |
| 101 DLOG(INFO) << "In callback function for the UpdateProperty signal"; |
| 102 DumpProperties(prop_list); |
| 103 } |
| 104 |
| 84 std::string xkb_id() const { | 105 std::string xkb_id() const { |
| 85 return xkb_id_; | 106 return xkb_id_; |
| 86 } | 107 } |
| 87 void set_xkb_id(const std::string& id) { | 108 void set_xkb_id(const std::string& id) { |
| 88 xkb_id_ = id; | 109 xkb_id_ = id; |
| 89 } | 110 } |
| 90 std::string ime_id() const { | 111 std::string ime_id() const { |
| 91 return ime_id_; | 112 return ime_id_; |
| 92 } | 113 } |
| 93 void set_ime_id(const std::string& id) { | 114 void set_ime_id(const std::string& id) { |
| 94 ime_id_ = id; | 115 ime_id_ = id; |
| 95 } | 116 } |
| 96 | 117 |
| 97 private: | 118 private: |
| 98 int count_; | 119 int count_; |
| 99 GMainLoop* loop_; | 120 GMainLoop* loop_; |
| 100 std::string xkb_id_; | 121 std::string xkb_id_; |
| 101 std::string ime_id_; | 122 std::string ime_id_; |
| 102 }; | 123 }; |
| 103 | 124 |
| 104 // Show the active languages. | 125 // Show the active languages. |
| 105 static void ShowActiveLanguages() { | 126 static void ShowActiveLanguages() { |
| 106 const scoped_ptr<chromeos::InputLanguageList> languages( | 127 const scoped_ptr<chromeos::InputLanguageList> languages( |
| 107 chromeos::GetLanguages(global_connection)); | 128 chromeos::GetLanguages(global_connection)); |
| 108 for (size_t i = 0; i < languages->size(); ++i) { | 129 for (size_t i = 0; i < languages->size(); ++i) { |
| 109 const chromeos::InputLanguage &language = languages->at(i); | 130 const chromeos::InputLanguage &language = languages->at(i); |
| 110 std::cout << "* " << language.display_name << std::endl; | 131 LOG(INFO) << "* " << language.display_name; |
| 111 } | 132 } |
| 112 } | 133 } |
| 113 | 134 |
| 114 int main(int argc, const char** argv) { | 135 int main(int argc, const char** argv) { |
| 115 // Initialize the g_type systems an g_main event loop, normally this would be | 136 // Initialize the g_type systems an g_main event loop, normally this would be |
| 116 // done by chrome. | 137 // done by chrome. |
| 117 ::g_type_init(); | 138 ::g_type_init(); |
| 118 GMainLoop* loop = ::g_main_loop_new(NULL, false); | 139 GMainLoop* loop = ::g_main_loop_new(NULL, false); |
| 119 DCHECK(LoadCrosLibrary(argv)) << "Failed to load cros.so"; | 140 DCHECK(LoadCrosLibrary(argv)) << "Failed to load cros.so"; |
| 120 | 141 |
| 142 chromeos::LanguageStatusMonitorFunctions monitor; |
| 143 monitor.current_language = &Callback::UpdateCurrentLanguage; |
| 144 monitor.register_ime_properties = &Callback::RegisterProperties; |
| 145 monitor.update_ime_property = &Callback::UpdateProperty; |
| 146 |
| 121 Callback callback(loop); | 147 Callback callback(loop); |
| 122 global_connection | 148 global_connection |
| 123 = chromeos::MonitorLanguageStatus(&Callback::Run, &callback); | 149 = chromeos::MonitorLanguageStatus(monitor, &callback); |
| 124 DCHECK(global_connection) << "MonitorLanguageStatus() failed. " | 150 DCHECK(global_connection) << "MonitorLanguageStatus() failed. " |
| 125 << "candidate_window is not running?"; | 151 << "candidate_window is not running?"; |
| 126 | 152 |
| 127 const scoped_ptr<chromeos::InputLanguageList> languages( | 153 const scoped_ptr<chromeos::InputLanguageList> languages( |
| 128 chromeos::GetLanguages(global_connection)); | 154 chromeos::GetLanguages(global_connection)); |
| 129 DCHECK(languages.get()) << "GetLanguages() failed"; | 155 DCHECK(languages.get()) << "GetLanguages() failed"; |
| 130 | 156 |
| 131 if (languages->empty()) { | 157 if (languages->empty()) { |
| 132 LOG(ERROR) << "No activated languages"; | 158 LOG(ERROR) << "No activated languages"; |
| 133 return 1; | 159 return 1; |
| 134 } | 160 } |
| 135 // Check if we have at least one IME. Languages are sorted in a way that | 161 // Check if we have at least one IME. Languages are sorted in a way that |
| 136 // IMEs come after XKBs, so we check the last language. | 162 // IMEs come after XKBs, so we check the last language. |
| 137 if (languages->back().category != chromeos::LANGUAGE_CATEGORY_IME) { | 163 if (languages->back().category != chromeos::LANGUAGE_CATEGORY_IME) { |
| 138 LOG(ERROR) << "No IME found"; | 164 LOG(ERROR) << "No IME found"; |
| 139 return 1; | 165 return 1; |
| 140 } | 166 } |
| 141 | 167 |
| 142 std::cout << "Activated IMEs and XKB layouts:" << std::endl; | 168 LOG(INFO) << "Activated IMEs and XKB layouts:"; |
| 143 for (size_t i = 0; i < languages->size(); ++i) { | 169 for (size_t i = 0; i < languages->size(); ++i) { |
| 144 const chromeos::InputLanguage &language = languages->at(i); | 170 const chromeos::InputLanguage &language = languages->at(i); |
| 145 std::cout << "* " << language.display_name << std::endl; | 171 LOG(INFO) << "* " << language.display_name; |
| 146 // Remember (at least) one XKB id and one IME id. | 172 // Remember (at least) one XKB id and one IME id. |
| 147 if (language.category == chromeos::LANGUAGE_CATEGORY_XKB) { | 173 if (language.category == chromeos::LANGUAGE_CATEGORY_XKB) { |
| 148 callback.set_xkb_id(language.id); | 174 callback.set_xkb_id(language.id); |
| 149 } else { | 175 } else { |
| 150 callback.set_ime_id(language.id); | 176 callback.set_ime_id(language.id); |
| 151 } | 177 } |
| 152 } | 178 } |
| 153 | 179 |
| 154 // Deactivate the last language for testing. | 180 // Deactivate the last language for testing. |
| 155 const chromeos::InputLanguage& language = languages->back(); | 181 const chromeos::InputLanguage& language = languages->back(); |
| 156 DCHECK(chromeos::DeactivateLanguage(global_connection, | 182 DCHECK(chromeos::DeactivateLanguage(global_connection, |
| 157 language.category, | 183 language.category, |
| 158 language.id.c_str())); | 184 language.id.c_str())); |
| 159 // This is not reliable, but wait for a moment so the config change | 185 // This is not reliable, but wait for a moment so the config change |
| 160 // takes effect in IBus. | 186 // takes effect in IBus. |
| 161 sleep(1); | 187 sleep(1); |
| 162 std::cout << "Deactivated: " << language.display_name << std::endl; | 188 LOG(INFO) << "Deactivated: " << language.display_name; |
| 163 ShowActiveLanguages(); | 189 ShowActiveLanguages(); |
| 164 | 190 |
| 165 // Reactivate the language. | 191 // Reactivate the language. |
| 166 DCHECK(chromeos::ActivateLanguage(global_connection, | 192 DCHECK(chromeos::ActivateLanguage(global_connection, |
| 167 language.category, | 193 language.category, |
| 168 language.id.c_str())); | 194 language.id.c_str())); |
| 169 sleep(1); | 195 sleep(1); |
| 170 std::cout << "Reactivated: " << language.display_name << std::endl; | 196 LOG(INFO) << "Reactivated: " << language.display_name; |
| 171 ShowActiveLanguages(); | 197 ShowActiveLanguages(); |
| 172 | 198 |
| 173 ::g_main_loop_run(loop); | 199 ::g_main_loop_run(loop); |
| 174 chromeos::DisconnectLanguageStatus(global_connection); | 200 chromeos::DisconnectLanguageStatus(global_connection); |
| 175 ::g_main_loop_unref(loop); | 201 ::g_main_loop_unref(loop); |
| 176 | 202 |
| 177 return 0; | 203 return 0; |
| 178 } | 204 } |
| OLD | NEW |