OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/input_method/ibus_controller_impl.h" | 5 #include "chrome/browser/chromeos/input_method/ibus_controller_impl.h" |
6 | 6 |
7 #include <algorithm> // for std::reverse. | 7 #include <algorithm> // for std::reverse. |
8 #include <cstdio> | 8 #include <cstdio> |
9 #include <cstring> // for std::strcmp. | 9 #include <cstring> // for std::strcmp. |
10 #include <set> | 10 #include <set> |
11 #include <sstream> | 11 #include <sstream> |
12 #include <stack> | 12 #include <stack> |
13 #include <utility> | 13 #include <utility> |
14 | 14 |
15 #include "base/bind.h" | |
16 #include "base/environment.h" | |
17 #include "base/files/file_path_watcher.h" | |
15 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
19 #include "base/message_loop.h" | |
20 #include "base/rand_util.h" | |
16 #include "base/stringprintf.h" | 21 #include "base/stringprintf.h" |
17 #include "base/string_split.h" | 22 #include "base/string_split.h" |
18 #include "chrome/browser/chromeos/input_method/input_method_config.h" | 23 #include "chrome/browser/chromeos/input_method/input_method_config.h" |
19 #include "chrome/browser/chromeos/input_method/input_method_property.h" | 24 #include "chrome/browser/chromeos/input_method/input_method_property.h" |
20 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 25 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
26 #include "chromeos/dbus/dbus_thread_manager.h" | |
27 #include "content/public/browser/browser_thread.h" | |
21 | 28 |
22 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests | 29 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests |
23 // for all functions in this file. crbug.com/26334 | 30 // for all functions in this file. crbug.com/26334 |
24 #if defined(HAVE_IBUS) | 31 #if defined(HAVE_IBUS) |
25 #include <ibus.h> | 32 #include <ibus.h> |
26 #endif | 33 #endif |
27 | 34 |
28 namespace { | 35 namespace { |
29 | 36 |
30 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the | 37 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 std::stringstream stream; | 357 std::stringstream stream; |
351 for (int i = 0;; ++i) { | 358 for (int i = 0;; ++i) { |
352 IBusProperty* prop = ibus_prop_list_get(prop_list, i); | 359 IBusProperty* prop = ibus_prop_list_get(prop_list, i); |
353 if (!prop) | 360 if (!prop) |
354 break; | 361 break; |
355 stream << PrintProp(prop, tree_level); | 362 stream << PrintProp(prop, tree_level); |
356 } | 363 } |
357 return stream.str(); | 364 return stream.str(); |
358 } | 365 } |
359 | 366 |
367 class IBusAddressWatcher { | |
368 public: | |
369 class IBusAddressFileWatcherDelegate | |
370 : public base::files::FilePathWatcher::Delegate { | |
371 public: | |
372 IBusAddressFileWatcherDelegate( | |
373 const std::string& ibus_address, | |
374 IBusControllerImpl* controller, | |
375 IBusAddressWatcher* watcher) | |
376 : ibus_address_(ibus_address), | |
377 controller_(controller), | |
378 watcher_(watcher) { | |
379 DCHECK(watcher); | |
380 DCHECK(!ibus_address.empty()); | |
381 } | |
382 | |
383 virtual ~IBusAddressFileWatcherDelegate() {} | |
384 | |
385 virtual void OnFilePathChanged(const FilePath& file_path) { | |
386 if (!watcher_->IsWatching()) | |
387 return; | |
388 bool success = content::BrowserThread::PostTask( | |
389 content::BrowserThread::UI, | |
390 FROM_HERE, | |
391 base::Bind( | |
392 &IBusControllerImpl::IBusDaemonInitializationDone, | |
393 controller_, | |
394 ibus_address_)); | |
395 DCHECK(success); | |
396 watcher_->StopSoon(); | |
397 } | |
398 | |
399 private: | |
400 // The ibus-daemon address. | |
401 const std::string ibus_address_; | |
402 IBusControllerImpl* controller_; | |
403 IBusAddressWatcher* watcher_; | |
404 | |
405 DISALLOW_COPY_AND_ASSIGN(IBusAddressFileWatcherDelegate); | |
406 }; | |
407 | |
408 static void Start(const std::string& ibus_address, | |
409 IBusControllerImpl* controller) { | |
410 IBusAddressWatcher* instance = IBusAddressWatcher::Get(); | |
411 scoped_ptr<base::Environment> env(base::Environment::Create()); | |
412 std::string address_file_path; | |
413 // TODO(nona): Moves reading environment variables to UI thread. | |
414 env->GetVar("IBUS_ADDRESS_FILE", &address_file_path); | |
415 DCHECK(!address_file_path.empty()); | |
416 | |
417 if (instance->IsWatching()) { | |
Yusuke Sato
2012/05/02 06:17:06
remove { }
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
418 instance->StopNow(); | |
419 } | |
420 instance->watcher_ = new base::files::FilePathWatcher; | |
421 | |
422 // The |delegate| is owned by watcher. | |
423 IBusAddressFileWatcherDelegate* delegate = | |
424 new IBusAddressFileWatcherDelegate(ibus_address, controller, instance); | |
425 bool result = instance->watcher_->Watch(FilePath(address_file_path), | |
426 delegate); | |
427 DCHECK(result); | |
428 } | |
429 | |
430 void StopNow() { | |
431 if (!watcher_) | |
Yusuke Sato
2012/05/02 06:17:06
nit: remove 431-432. deleting NULL is safe.
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
432 return; | |
433 delete watcher_; | |
434 watcher_ = NULL; | |
435 } | |
436 | |
437 void StopSoon() { | |
438 if (!watcher_) | |
439 return; | |
440 MessageLoop::current()->DeleteSoon(FROM_HERE, watcher_); | |
441 watcher_ = NULL; | |
442 } | |
443 | |
444 bool IsWatching() { | |
Yusuke Sato
2012/05/02 06:17:06
nit: const
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
445 return watcher_ != NULL; | |
446 } | |
447 | |
448 private: | |
449 static IBusAddressWatcher* Get() { | |
450 static IBusAddressWatcher* instance = new IBusAddressWatcher; | |
Yusuke Sato
2012/05/02 06:17:06
add a thread ID check like DCHECK(content::Browser
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
451 return instance; | |
452 } | |
453 | |
454 // Singleton | |
455 IBusAddressWatcher() | |
456 : watcher_(NULL) {} | |
457 base::files::FilePathWatcher* watcher_; | |
458 DISALLOW_COPY_AND_ASSIGN(IBusAddressWatcher); | |
Yusuke Sato
2012/05/02 06:17:06
nit: space between 457 & 458
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
459 }; | |
460 | |
360 } // namespace | 461 } // namespace |
361 | 462 |
362 IBusControllerImpl::IBusControllerImpl() | 463 IBusControllerImpl::IBusControllerImpl() |
363 : ibus_(NULL), | 464 : ibus_(NULL), |
364 ibus_config_(NULL), | 465 ibus_config_(NULL), |
365 should_launch_daemon_(false), | 466 process_handle_(base::kNullProcessHandle), |
366 process_handle_(base::kNullProcessHandle) { | 467 ibus_daemon_status_(IBUS_DAEMON_STOP), |
468 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
367 } | 469 } |
368 | 470 |
369 IBusControllerImpl::~IBusControllerImpl() { | 471 IBusControllerImpl::~IBusControllerImpl() { |
370 // Disconnect signals so the handler functions will not be called with | 472 // Disconnect signals so the handler functions will not be called with |
371 // |this| which is already freed. | 473 // |this| which is already freed. |
372 if (ibus_) { | 474 if (ibus_) { |
373 g_signal_handlers_disconnect_by_func( | 475 g_signal_handlers_disconnect_by_func( |
374 ibus_, | 476 ibus_, |
375 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)), | 477 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)), |
376 this); | 478 this); |
(...skipping 21 matching lines...) Expand all Loading... | |
398 g_signal_handlers_disconnect_by_func( | 500 g_signal_handlers_disconnect_by_func( |
399 ibus_panel_service, | 501 ibus_panel_service, |
400 reinterpret_cast<gpointer>(G_CALLBACK(UpdatePropertyThunk)), | 502 reinterpret_cast<gpointer>(G_CALLBACK(UpdatePropertyThunk)), |
401 this); | 503 this); |
402 } | 504 } |
403 } | 505 } |
404 } | 506 } |
405 | 507 |
406 bool IBusControllerImpl::Start() { | 508 bool IBusControllerImpl::Start() { |
407 MaybeInitializeIBusBus(); | 509 MaybeInitializeIBusBus(); |
408 should_launch_daemon_ = true; | |
409 if (IBusConnectionsAreAlive()) | 510 if (IBusConnectionsAreAlive()) |
410 return true; | 511 return true; |
411 return MaybeLaunchIBusDaemon(); | 512 if (ibus_daemon_status_ == IBUS_DAEMON_STOP || |
513 ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN) { | |
514 return StartIBusDaemon(); | |
515 } | |
516 return true; | |
412 } | 517 } |
413 | 518 |
414 void IBusControllerImpl::Reset() { | 519 void IBusControllerImpl::Reset() { |
415 if (!IBusConnectionsAreAlive()) | 520 if (!IBusConnectionsAreAlive()) |
416 return; | 521 return; |
417 IBusInputContext* context = | 522 IBusInputContext* context = |
418 GetInputContext(current_input_context_path_, ibus_); | 523 GetInputContext(current_input_context_path_, ibus_); |
419 if (!context) | 524 if (!context) |
420 return; | 525 return; |
421 ibus_input_context_reset(context); | 526 ibus_input_context_reset(context); |
422 } | 527 } |
423 | 528 |
424 bool IBusControllerImpl::Stop() { | 529 bool IBusControllerImpl::Stop() { |
530 if (ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN || | |
531 ibus_daemon_status_ == IBUS_DAEMON_STOP) { | |
532 // The daemon hasn't been started yet or now shutting down. | |
533 return true; | |
534 } | |
535 | |
536 ibus_daemon_status_ = IBUS_DAEMON_SHUTTING_DOWN; | |
537 // TODO(nona): Shutdown ibus-bus connection. | |
425 if (IBusConnectionsAreAlive()) { | 538 if (IBusConnectionsAreAlive()) { |
426 // Ask IBus to exit *asynchronously*. | 539 // Ask IBus to exit *asynchronously*. |
427 ibus_bus_exit_async(ibus_, | 540 ibus_bus_exit_async(ibus_, |
428 FALSE /* do not restart */, | 541 FALSE /* do not restart */, |
429 -1 /* timeout */, | 542 -1 /* timeout */, |
430 NULL /* cancellable */, | 543 NULL /* cancellable */, |
431 NULL /* callback */, | 544 NULL /* callback */, |
432 NULL /* user_data */); | 545 NULL /* user_data */); |
433 if (ibus_config_) { | 546 if (ibus_config_) { |
434 // Release |ibus_config_| unconditionally to make sure next | 547 // Release |ibus_config_| unconditionally to make sure next |
435 // IBusConnectionsAreAlive() call will return false. | 548 // IBusConnectionsAreAlive() call will return false. |
436 g_object_unref(ibus_config_); | 549 g_object_unref(ibus_config_); |
437 ibus_config_ = NULL; | 550 ibus_config_ = NULL; |
438 } | 551 } |
439 } else if (process_handle_ != base::kNullProcessHandle) { | 552 } else { |
440 base::KillProcess(process_handle_, -1, false /* wait */); | 553 base::KillProcess(process_handle_, -1, false /* wait */); |
441 DVLOG(1) << "Killing ibus-daemon. PID=" | 554 DVLOG(1) << "Killing ibus-daemon. PID=" |
442 << base::GetProcId(process_handle_); | 555 << base::GetProcId(process_handle_); |
443 } else { | |
444 // The daemon hasn't been started yet. | |
445 } | 556 } |
446 | |
447 process_handle_ = base::kNullProcessHandle; | 557 process_handle_ = base::kNullProcessHandle; |
448 should_launch_daemon_ = false; | |
449 return true; | 558 return true; |
450 } | 559 } |
451 | 560 |
452 bool IBusControllerImpl::ChangeInputMethod(const std::string& id) { | 561 bool IBusControllerImpl::ChangeInputMethod(const std::string& id) { |
453 DCHECK(should_launch_daemon_); | 562 // TODO(nona): use ibus_daemon_state_ after implement crosbug/26334 |
Yusuke Sato
2012/05/02 06:17:06
??
looks like you're already checking |ibus_daemo
Seigo Nonaka
2012/05/02 18:09:13
Oops this comment is obsolete.
Removed.
On 2012/0
| |
563 if (ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN || | |
564 ibus_daemon_status_ == IBUS_DAEMON_STOP) { | |
565 return false; | |
566 } | |
454 | 567 |
455 // Sanity checks. | 568 // Sanity checks. |
456 DCHECK(!InputMethodUtil::IsKeyboardLayout(id)); | 569 DCHECK(!InputMethodUtil::IsKeyboardLayout(id)); |
457 if (!whitelist_.InputMethodIdIsWhitelisted(id) && | 570 if (!whitelist_.InputMethodIdIsWhitelisted(id) && |
458 !InputMethodUtil::IsExtensionInputMethod(id)) | 571 !InputMethodUtil::IsExtensionInputMethod(id)) |
459 return false; | 572 return false; |
460 | 573 |
461 // Clear input method properties unconditionally if |id| is not equal to | 574 // Clear input method properties unconditionally if |id| is not equal to |
462 // |current_input_method_id_|. | 575 // |current_input_method_id_|. |
463 // | 576 // |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 IBusInputContext* context = | 678 IBusInputContext* context = |
566 GetInputContext(current_input_context_path_, ibus_); | 679 GetInputContext(current_input_context_path_, ibus_); |
567 if (!context) | 680 if (!context) |
568 return; | 681 return; |
569 ibus_input_context_cancel_hand_writing(context, n_strokes); | 682 ibus_input_context_cancel_hand_writing(context, n_strokes); |
570 g_object_unref(context); | 683 g_object_unref(context); |
571 } | 684 } |
572 #endif | 685 #endif |
573 | 686 |
574 bool IBusControllerImpl::IBusConnectionsAreAlive() { | 687 bool IBusControllerImpl::IBusConnectionsAreAlive() { |
575 return (process_handle_ != base::kNullProcessHandle) && | 688 return (ibus_daemon_status_ == IBUS_DAEMON_RUNNING) && |
576 ibus_ && ibus_bus_is_connected(ibus_) && ibus_config_; | 689 ibus_ && ibus_bus_is_connected(ibus_) && ibus_config_; |
577 } | 690 } |
578 | 691 |
579 void IBusControllerImpl::MaybeRestoreConnections() { | 692 void IBusControllerImpl::MaybeRestoreConnections() { |
580 if (IBusConnectionsAreAlive()) | 693 if (IBusConnectionsAreAlive()) |
581 return; | 694 return; |
582 MaybeRestoreIBusConfig(); | 695 MaybeRestoreIBusConfig(); |
583 if (IBusConnectionsAreAlive()) { | 696 if (IBusConnectionsAreAlive()) { |
584 DVLOG(1) << "ibus-daemon and ibus-memconf processes are ready."; | 697 DVLOG(1) << "ibus-daemon and ibus-memconf processes are ready."; |
585 ConnectPanelServiceSignals(); | 698 ConnectPanelServiceSignals(); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 | 998 |
886 // Notify the change. | 999 // Notify the change. |
887 if (!prop_list.empty()) { | 1000 if (!prop_list.empty()) { |
888 for (size_t i = 0; i < prop_list.size(); ++i) { | 1001 for (size_t i = 0; i < prop_list.size(); ++i) { |
889 FindAndUpdateProperty(prop_list[i], ¤t_property_list_); | 1002 FindAndUpdateProperty(prop_list[i], ¤t_property_list_); |
890 } | 1003 } |
891 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); | 1004 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); |
892 } | 1005 } |
893 } | 1006 } |
894 | 1007 |
895 bool IBusControllerImpl::MaybeLaunchIBusDaemon() { | 1008 bool IBusControllerImpl::StartIBusDaemon() { |
896 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; | 1009 if (ibus_daemon_status_ == IBUS_DAEMON_INITIALIZING || |
897 | 1010 ibus_daemon_status_ == IBUS_DAEMON_RUNNING) { |
898 if (process_handle_ != base::kNullProcessHandle) { | |
899 DVLOG(1) << "MaybeLaunchIBusDaemon: ibus-daemon is already running."; | |
900 return false; | 1011 return false; |
Yusuke Sato
2012/05/02 06:17:06
keep the DVLOG(1) for now.
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
901 } | 1012 } |
902 if (!should_launch_daemon_) | |
903 return false; | |
904 | 1013 |
1014 ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING; | |
1015 const std::string ibus_address = base::StringPrintf( | |
1016 "unix:abstract=ibus-%0lX", base::RandUint64()); | |
1017 | |
1018 // Set up ibus-daemon address file watcher before launching ibus-daemon, | |
1019 // because if watcher start after ibus-daemon, we may miss the ibus connection | |
1020 // initialization. | |
1021 bool success = content::BrowserThread::PostTaskAndReply( | |
1022 content::BrowserThread::FILE, | |
1023 FROM_HERE, | |
1024 base::Bind(&IBusAddressWatcher::Start, | |
1025 ibus_address, | |
1026 base::Unretained(this)), | |
1027 base::Bind(&IBusControllerImpl::LaunchIBusDaemon, | |
1028 weak_ptr_factory_.GetWeakPtr(), | |
1029 ibus_address)); | |
1030 DCHECK(success); | |
1031 return true; | |
1032 } | |
1033 | |
1034 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) { | |
Yusuke Sato
2012/05/02 06:17:06
update ibus_daemon_address_ in this function.
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
1035 DCHECK_EQ(base::kNullProcessHandle, process_handle_); | |
1036 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; | |
905 // TODO(zork): Send output to /var/log/ibus.log | 1037 // TODO(zork): Send output to /var/log/ibus.log |
906 const std::string ibus_daemon_command_line = | 1038 const std::string ibus_daemon_command_line = |
907 base::StringPrintf("%s --panel=disable --cache=none --restart --replace", | 1039 base::StringPrintf("%s --panel=disable --cache=none --restart --replace" |
908 kIBusDaemonPath); | 1040 " --address=%s", |
1041 kIBusDaemonPath, | |
1042 ibus_address.c_str()); | |
909 if (!LaunchProcess(ibus_daemon_command_line, | 1043 if (!LaunchProcess(ibus_daemon_command_line, |
910 &process_handle_, | 1044 &process_handle_, |
911 reinterpret_cast<GChildWatchFunc>(OnIBusDaemonExit))) { | 1045 reinterpret_cast<GChildWatchFunc>(OnIBusDaemonExit))) { |
912 DVLOG(1) << "Failed to launch " << ibus_daemon_command_line; | 1046 DVLOG(1) << "Failed to launch " << ibus_daemon_command_line; |
913 return false; | |
914 } | 1047 } |
915 return true; | |
916 } | 1048 } |
917 | 1049 |
918 bool IBusControllerImpl::LaunchProcess(const std::string& command_line, | 1050 bool IBusControllerImpl::LaunchProcess(const std::string& command_line, |
919 base::ProcessHandle* process_handle, | 1051 base::ProcessHandle* process_handle, |
920 GChildWatchFunc watch_func) { | 1052 GChildWatchFunc watch_func) { |
921 std::vector<std::string> argv; | 1053 std::vector<std::string> argv; |
922 base::ProcessHandle handle = base::kNullProcessHandle; | 1054 base::ProcessHandle handle = base::kNullProcessHandle; |
923 | 1055 |
924 base::SplitString(command_line, ' ', &argv); | 1056 base::SplitString(command_line, ' ', &argv); |
925 | 1057 |
926 if (!base::LaunchProcess(argv, base::LaunchOptions(), &handle)) { | 1058 if (!base::LaunchProcess(argv, base::LaunchOptions(), &handle)) { |
927 DVLOG(1) << "Could not launch: " << command_line; | 1059 DVLOG(1) << "Could not launch: " << command_line; |
928 return false; | 1060 return false; |
929 } | 1061 } |
930 | 1062 |
931 // g_child_watch_add is necessary to prevent the process from becoming a | 1063 // g_child_watch_add is necessary to prevent the process from becoming a |
932 // zombie. | 1064 // zombie. |
933 // TODO(yusukes): port g_child_watch_add to base/process_utils_posix.cc. | 1065 // TODO(yusukes): port g_child_watch_add to base/process_utils_posix.cc. |
934 const base::ProcessId pid = base::GetProcId(handle); | 1066 const base::ProcessId pid = base::GetProcId(handle); |
935 g_child_watch_add(pid, watch_func, this); | 1067 g_child_watch_add(pid, watch_func, this); |
936 | 1068 |
937 *process_handle = handle; | 1069 *process_handle = handle; |
938 DVLOG(1) << command_line << "is started. PID=" << pid; | 1070 DVLOG(1) << command_line << "is started. PID=" << pid; |
939 return true; | 1071 return true; |
940 } | 1072 } |
941 | 1073 |
942 // static | 1074 // static |
1075 void IBusControllerImpl::IBusDaemonInitializationDone( | |
1076 IBusControllerImpl* controller, | |
1077 const std::string& ibus_address) { | |
1078 if (controller->ibus_daemon_address_ != ibus_address) | |
1079 return; | |
1080 | |
1081 if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { | |
1082 // Corresponding to killing ibus-daemon under initializing, so do nothing. | |
1083 return; | |
1084 } | |
1085 chromeos::DBusThreadManager::Get()->MaybeResetIBusBus(ibus_address); | |
1086 controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING; | |
1087 } | |
1088 | |
1089 // static | |
943 void IBusControllerImpl::SetInputMethodConfigCallback(GObject* source_object, | 1090 void IBusControllerImpl::SetInputMethodConfigCallback(GObject* source_object, |
944 GAsyncResult* res, | 1091 GAsyncResult* res, |
945 gpointer user_data) { | 1092 gpointer user_data) { |
946 IBusConfig* config = IBUS_CONFIG(user_data); | 1093 IBusConfig* config = IBUS_CONFIG(user_data); |
947 g_return_if_fail(config); | 1094 g_return_if_fail(config); |
948 | 1095 |
949 GError* error = NULL; | 1096 GError* error = NULL; |
950 const gboolean result = | 1097 const gboolean result = |
951 ibus_config_set_value_async_finish(config, res, &error); | 1098 ibus_config_set_value_async_finish(config, res, &error); |
952 | 1099 |
953 if (!result) { | 1100 if (!result) { |
954 std::string message = "(unknown error)"; | 1101 std::string message = "(unknown error)"; |
955 if (error && error->message) { | 1102 if (error && error->message) { |
956 message = error->message; | 1103 message = error->message; |
957 } | 1104 } |
958 DVLOG(1) << "ibus_config_set_value_async failed: " << message; | 1105 DVLOG(1) << "ibus_config_set_value_async failed: " << message; |
959 } | 1106 } |
960 | 1107 |
961 if (error) | 1108 if (error) |
962 g_error_free(error); | 1109 g_error_free(error); |
963 g_object_unref(config); | 1110 g_object_unref(config); |
964 } | 1111 } |
965 | 1112 |
966 // static | 1113 // static |
967 void IBusControllerImpl::OnIBusDaemonExit(GPid pid, | 1114 void IBusControllerImpl::OnIBusDaemonExit(GPid pid, |
968 gint status, | 1115 gint status, |
969 IBusControllerImpl* controller) { | 1116 IBusControllerImpl* controller) { |
970 if (controller->process_handle_ != base::kNullProcessHandle && | 1117 const IBusDaemonStatus on_exit_state = controller->ibus_daemon_status_; |
Yusuke Sato
2012/05/02 06:17:06
nit: move this down to 1135.
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
971 base::GetProcId(controller->process_handle_) == pid) { | 1118 |
972 controller->process_handle_ = base::kNullProcessHandle; | 1119 if (controller->process_handle_ != base::kNullProcessHandle) { |
1120 if (base::GetProcId(controller->process_handle_) == pid) { | |
1121 // Corresponding to shutting down ibus-daemon by exit message or crashing | |
1122 // ibus-daemon. So reset handler and try re-launch if necessary. | |
1123 controller->process_handle_ = base::kNullProcessHandle; | |
1124 } else { | |
1125 // This condition is corresponding as follows. | |
1126 // 1. Called Stop (process_handle_ become null) | |
1127 // 2. Called LaunchProcess (process_handle_ become new instance | |
Yusuke Sato
2012/05/02 06:17:06
)
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
1128 // 3. Callbacked OnIBusDaemonExit for old instance and reach here. | |
1129 // In this case, we should not reset process_handle_ as null, and do not | |
1130 // re-launch ibus-daemon. | |
1131 // TODO(nona): Shutdown ibus-bus connection. | |
1132 return; | |
1133 } | |
973 } | 1134 } |
974 // Restart the daemon if needed. | 1135 |
975 controller->MaybeLaunchIBusDaemon(); | 1136 controller->ibus_daemon_status_ = IBUS_DAEMON_STOP; |
1137 if (on_exit_state == IBUS_DAEMON_SHUTTING_DOWN) { | |
1138 // Normal exitting, so do nothing. | |
1139 return; | |
1140 } | |
1141 | |
1142 LOG(ERROR) << "The ibus-daemon is crashed. Re-launching..."; | |
Yusuke Sato
2012/05/02 06:17:06
s/is//
Seigo Nonaka
2012/05/02 18:09:13
Done.
| |
1143 controller->StartIBusDaemon(); | |
976 } | 1144 } |
977 #endif // defined(HAVE_IBUS) | 1145 #endif // defined(HAVE_IBUS) |
978 | 1146 |
979 // static | 1147 // static |
980 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( | 1148 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( |
981 const chromeos::input_method::InputMethodProperty& new_prop, | 1149 const chromeos::input_method::InputMethodProperty& new_prop, |
982 chromeos::input_method::InputMethodPropertyList* prop_list) { | 1150 chromeos::input_method::InputMethodPropertyList* prop_list) { |
983 return FindAndUpdateProperty(new_prop, prop_list); | 1151 return FindAndUpdateProperty(new_prop, prop_list); |
984 } | 1152 } |
985 | 1153 |
986 } // namespace input_method | 1154 } // namespace input_method |
987 } // namespace chromeos | 1155 } // namespace chromeos |
OLD | NEW |