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" |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/browser_thread.h" | 16 #include "chrome/browser/browser_thread.h" |
17 #include "chrome/browser/chromeos/cros/cros_library.h" | 17 #include "chrome/browser/chromeos/cros/cros_library.h" |
18 #include "chrome/browser/chromeos/cros/keyboard_library.h" | 18 #include "chrome/browser/chromeos/cros/keyboard_library.h" |
19 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 19 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
20 #include "chrome/browser/chromeos/language_preferences.h" | 20 #include "chrome/browser/chromeos/language_preferences.h" |
21 #include "chrome/common/notification_observer.h" | 21 #include "chrome/common/notification_observer.h" |
22 #include "chrome/common/notification_registrar.h" | 22 #include "chrome/common/notification_registrar.h" |
23 #include "chrome/common/notification_service.h" | 23 #include "chrome/common/notification_service.h" |
24 | 24 |
25 namespace { | 25 namespace { |
| 26 |
26 const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; | 27 const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; |
27 const char kCandidateWindowPath[] = "/opt/google/chrome/candidate_window"; | 28 const char kCandidateWindowPath[] = "/opt/google/chrome/candidate_window"; |
28 | 29 |
29 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the | 30 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the |
30 // property with |new_prop|. Returns true if such a property is found. | 31 // property with |new_prop|. Returns true if such a property is found. |
31 bool FindAndUpdateProperty(const chromeos::ImeProperty& new_prop, | 32 bool FindAndUpdateProperty(const chromeos::ImeProperty& new_prop, |
32 chromeos::ImePropertyList* prop_list) { | 33 chromeos::ImePropertyList* prop_list) { |
33 for (size_t i = 0; i < prop_list->size(); ++i) { | 34 for (size_t i = 0; i < prop_list->size(); ++i) { |
34 chromeos::ImeProperty& prop = prop_list->at(i); | 35 chromeos::ImeProperty& prop = prop_list->at(i); |
35 if (prop.key == new_prop.key) { | 36 if (prop.key == new_prop.key) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 if (pending_config_requests_.empty()) { | 284 if (pending_config_requests_.empty()) { |
284 timer_.Stop(); // no-op if it's not running. | 285 timer_.Stop(); // no-op if it's not running. |
285 } else if (!timer_.IsRunning()) { | 286 } else if (!timer_.IsRunning()) { |
286 // Flush is not completed. Start a timer if it's not yet running. | 287 // Flush is not completed. Start a timer if it's not yet running. |
287 static const int64 kTimerIntervalInMsec = 100; | 288 static const int64 kTimerIntervalInMsec = 100; |
288 timer_.Start(base::TimeDelta::FromMilliseconds(kTimerIntervalInMsec), | 289 timer_.Start(base::TimeDelta::FromMilliseconds(kTimerIntervalInMsec), |
289 this, &InputMethodLibraryImpl::FlushImeConfig); | 290 this, &InputMethodLibraryImpl::FlushImeConfig); |
290 } | 291 } |
291 | 292 |
292 if (active_input_methods_are_changed) { | 293 if (active_input_methods_are_changed) { |
293 FOR_EACH_OBSERVER(Observer, observers_, ActiveInputMethodsChanged(this)); | 294 const size_t num_active_input_methods = GetNumActiveInputMethods(); |
| 295 FOR_EACH_OBSERVER(Observer, observers_, |
| 296 ActiveInputMethodsChanged(this, |
| 297 current_input_method_, |
| 298 num_active_input_methods)); |
294 } | 299 } |
295 } | 300 } |
296 | 301 |
297 static void InputMethodChangedHandler( | 302 static void InputMethodChangedHandler( |
298 void* object, | 303 void* object, |
299 const chromeos::InputMethodDescriptor& current_input_method) { | 304 const chromeos::InputMethodDescriptor& current_input_method) { |
300 // The handler is called when the input method method change is | 305 // The handler is called when the input method method change is |
301 // notified via a DBus connection. Since the DBus notificatiosn are | 306 // notified via a DBus connection. Since the DBus notificatiosn are |
302 // handled in the UI thread, we can assume that this functionalways | 307 // handled in the UI thread, we can assume that this functionalways |
303 // runs on the UI thread, but just in case. | 308 // runs on the UI thread, but just in case. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 | 384 |
380 void ChangeCurrentInputMethod(const InputMethodDescriptor& new_input_method) { | 385 void ChangeCurrentInputMethod(const InputMethodDescriptor& new_input_method) { |
381 // Change the keyboard layout to a preferred layout for the input method. | 386 // Change the keyboard layout to a preferred layout for the input method. |
382 CrosLibrary::Get()->GetKeyboardLibrary()->SetCurrentKeyboardLayoutByName( | 387 CrosLibrary::Get()->GetKeyboardLibrary()->SetCurrentKeyboardLayoutByName( |
383 new_input_method.keyboard_layout); | 388 new_input_method.keyboard_layout); |
384 | 389 |
385 if (current_input_method_.id != new_input_method.id) { | 390 if (current_input_method_.id != new_input_method.id) { |
386 previous_input_method_ = current_input_method_; | 391 previous_input_method_ = current_input_method_; |
387 current_input_method_ = new_input_method; | 392 current_input_method_ = new_input_method; |
388 } | 393 } |
389 FOR_EACH_OBSERVER(Observer, observers_, InputMethodChanged(this)); | 394 const size_t num_active_input_methods = GetNumActiveInputMethods(); |
| 395 FOR_EACH_OBSERVER(Observer, observers_, |
| 396 InputMethodChanged(this, |
| 397 previous_input_method_, |
| 398 current_input_method_, |
| 399 num_active_input_methods)); |
| 400 |
| 401 // Ask the first observer to update preferences. We should not ask every |
| 402 // observer to do so. Otherwise, we'll end up updating preferences many |
| 403 // times when many observers are attached (ex. many windows are opened), |
| 404 // which is unnecessary and expensive. |
| 405 ObserverListBase<Observer>::Iterator it(observers_); |
| 406 Observer* first_observer = it.GetNext(); |
| 407 if (first_observer) { |
| 408 first_observer->PreferenceUpdateNeeded(this, |
| 409 previous_input_method_, |
| 410 current_input_method_); |
| 411 } |
390 } | 412 } |
391 | 413 |
392 void RegisterProperties(const ImePropertyList& prop_list) { | 414 void RegisterProperties(const ImePropertyList& prop_list) { |
393 // |prop_list| might be empty. This means "clear all properties." | 415 // |prop_list| might be empty. This means "clear all properties." |
394 current_ime_properties_ = prop_list; | 416 current_ime_properties_ = prop_list; |
395 FOR_EACH_OBSERVER(Observer, observers_, ImePropertiesChanged(this)); | |
396 } | 417 } |
397 | 418 |
398 void StartInputMethodProcesses() { | 419 void StartInputMethodProcesses() { |
399 should_launch_ime_ = true; | 420 should_launch_ime_ = true; |
400 MaybeLaunchInputMethodProcesses(); | 421 MaybeLaunchInputMethodProcesses(); |
401 } | 422 } |
402 | 423 |
403 void UpdateProperty(const ImePropertyList& prop_list) { | 424 void UpdateProperty(const ImePropertyList& prop_list) { |
404 for (size_t i = 0; i < prop_list.size(); ++i) { | 425 for (size_t i = 0; i < prop_list.size(); ++i) { |
405 FindAndUpdateProperty(prop_list[i], ¤t_ime_properties_); | 426 FindAndUpdateProperty(prop_list[i], ¤t_ime_properties_); |
406 } | 427 } |
407 FOR_EACH_OBSERVER(Observer, observers_, ImePropertiesChanged(this)); | |
408 } | 428 } |
409 | 429 |
410 // Launches an input method procsess specified by the given command | 430 // Launches an input method procsess specified by the given command |
411 // line. On success, returns true and stores the process ID in | 431 // line. On success, returns true and stores the process ID in |
412 // |process_id|. Otherwise, returns false, and the contents of | 432 // |process_id|. Otherwise, returns false, and the contents of |
413 // |process_id| is untouched. OnImeShutdown will be called when the | 433 // |process_id| is untouched. OnImeShutdown will be called when the |
414 // process terminates. | 434 // process terminates. |
415 bool LaunchInputMethodProcess(const std::string& command_line, | 435 bool LaunchInputMethodProcess(const std::string& command_line, |
416 int* process_id) { | 436 int* process_id) { |
417 GError *error = NULL; | 437 GError *error = NULL; |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 return new InputMethodLibraryStubImpl(); | 808 return new InputMethodLibraryStubImpl(); |
789 else | 809 else |
790 return new InputMethodLibraryImpl(); | 810 return new InputMethodLibraryImpl(); |
791 } | 811 } |
792 | 812 |
793 } // namespace chromeos | 813 } // namespace chromeos |
794 | 814 |
795 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 815 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
796 // won't be deleted until it's last InvokeLater is run. | 816 // won't be deleted until it's last InvokeLater is run. |
797 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); | 817 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::InputMethodLibraryImpl); |
OLD | NEW |