Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: chrome/browser/chromeos/input_method/ibus_controller_impl.cc

Issue 11419202: Remove libibus dependency from config relate stuff. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "ash/shell.h" 15 #include "ash/shell.h"
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/environment.h" 17 #include "base/environment.h"
18 #include "base/files/file_path_watcher.h" 18 #include "base/files/file_path_watcher.h"
19 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
20 #include "base/message_loop.h" 20 #include "base/message_loop.h"
21 #include "base/rand_util.h" 21 #include "base/rand_util.h"
22 #include "base/string_split.h"
22 #include "base/stringprintf.h" 23 #include "base/stringprintf.h"
23 #include "base/string_split.h"
24 #include "chrome/browser/chromeos/input_method/input_method_config.h" 24 #include "chrome/browser/chromeos/input_method/input_method_config.h"
25 #include "chrome/browser/chromeos/input_method/input_method_property.h" 25 #include "chrome/browser/chromeos/input_method/input_method_property.h"
26 #include "chrome/browser/chromeos/input_method/input_method_util.h" 26 #include "chrome/browser/chromeos/input_method/input_method_util.h"
27 #include "chromeos/dbus/dbus_thread_manager.h" 27 #include "chromeos/dbus/dbus_thread_manager.h"
28 #include "chromeos/dbus/ibus/ibus_config_client.h"
28 #include "chromeos/dbus/ibus/ibus_constants.h" 29 #include "chromeos/dbus/ibus/ibus_constants.h"
29 #include "chromeos/dbus/ibus/ibus_input_context_client.h" 30 #include "chromeos/dbus/ibus/ibus_input_context_client.h"
30 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
31 #include "ui/aura/client/aura_constants.h" 32 #include "ui/aura/client/aura_constants.h"
32 #include "ui/aura/root_window.h" 33 #include "ui/aura/root_window.h"
33 #include "ui/base/ime/input_method_ibus.h" 34 #include "ui/base/ime/input_method_ibus.h"
34 35
35 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests 36 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests
36 // for all functions in this file. crbug.com/26334 37 // for all functions in this file. crbug.com/26334
37 #if defined(HAVE_IBUS) 38 #if defined(HAVE_IBUS)
(...skipping 14 matching lines...) Expand all
52 // Update the list except the radio id. As written in 53 // Update the list except the radio id. As written in
53 // chromeos_input_method.h, |prop.selection_item_id| is dummy. 54 // chromeos_input_method.h, |prop.selection_item_id| is dummy.
54 prop = new_prop; 55 prop = new_prop;
55 prop.selection_item_id = saved_id; 56 prop.selection_item_id = saved_id;
56 return true; 57 return true;
57 } 58 }
58 } 59 }
59 return false; 60 return false;
60 } 61 }
61 62
63 void ConfigSetValueErrorCallback() {
64 DVLOG(1) << "IBusConfig: SetValue is failed.";
65 }
66
62 } // namespace 67 } // namespace
63 68
64 namespace chromeos { 69 namespace chromeos {
65 namespace input_method { 70 namespace input_method {
66 71
67 #if defined(HAVE_IBUS) 72 #if defined(HAVE_IBUS)
68 const char kPanelObjectKey[] = "panel-object"; 73 const char kPanelObjectKey[] = "panel-object";
69 74
70 namespace { 75 namespace {
71 76
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 : watcher_(NULL) {} 449 : watcher_(NULL) {}
445 base::files::FilePathWatcher* watcher_; 450 base::files::FilePathWatcher* watcher_;
446 451
447 DISALLOW_COPY_AND_ASSIGN(IBusAddressWatcher); 452 DISALLOW_COPY_AND_ASSIGN(IBusAddressWatcher);
448 }; 453 };
449 454
450 } // namespace 455 } // namespace
451 456
452 IBusControllerImpl::IBusControllerImpl() 457 IBusControllerImpl::IBusControllerImpl()
453 : ibus_(NULL), 458 : ibus_(NULL),
454 ibus_config_(NULL),
455 process_handle_(base::kNullProcessHandle), 459 process_handle_(base::kNullProcessHandle),
456 ibus_daemon_status_(IBUS_DAEMON_STOP), 460 ibus_daemon_status_(IBUS_DAEMON_STOP),
457 input_method_(NULL), 461 input_method_(NULL),
458 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 462 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
459 } 463 }
460 464
461 IBusControllerImpl::~IBusControllerImpl() { 465 IBusControllerImpl::~IBusControllerImpl() {
462 // Disconnect signals so the handler functions will not be called with 466 // Disconnect signals so the handler functions will not be called with
463 // |this| which is already freed. 467 // |this| which is already freed.
464 if (ibus_) { 468 if (ibus_) {
465 g_signal_handlers_disconnect_by_func( 469 g_signal_handlers_disconnect_by_func(
466 ibus_, 470 ibus_,
467 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)), 471 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)),
468 this); 472 this);
469 g_signal_handlers_disconnect_by_func(
470 ibus_,
471 reinterpret_cast<gpointer>(G_CALLBACK(BusDisconnectedThunk)),
472 this);
473 g_signal_handlers_disconnect_by_func(
474 ibus_,
475 reinterpret_cast<gpointer>(G_CALLBACK(BusNameOwnerChangedThunk)),
476 this);
477
478 // Disconnect signals for the panel service as well. 473 // Disconnect signals for the panel service as well.
479 // When Chrome is shutting down, g_object_get_data fails and returns NULL. 474 // When Chrome is shutting down, g_object_get_data fails and returns NULL.
480 // TODO(nona): Investigate the reason of failure(crosbug.com/129142). 475 // TODO(nona): Investigate the reason of failure(crosbug.com/129142).
481 void* attached_data = g_object_get_data(G_OBJECT(ibus_), kPanelObjectKey); 476 void* attached_data = g_object_get_data(G_OBJECT(ibus_), kPanelObjectKey);
482 if (!attached_data) 477 if (!attached_data)
483 return; 478 return;
484 if (!G_TYPE_CHECK_INSTANCE_TYPE(attached_data, IBUS_TYPE_PANEL_SERVICE)) 479 if (!G_TYPE_CHECK_INSTANCE_TYPE(attached_data, IBUS_TYPE_PANEL_SERVICE))
485 return; 480 return;
486 IBusPanelService* ibus_panel_service = IBUS_PANEL_SERVICE(attached_data); 481 IBusPanelService* ibus_panel_service = IBUS_PANEL_SERVICE(attached_data);
487 if (ibus_panel_service) { 482 if (ibus_panel_service) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 ibus_daemon_status_ = IBUS_DAEMON_SHUTTING_DOWN; 521 ibus_daemon_status_ = IBUS_DAEMON_SHUTTING_DOWN;
527 // TODO(nona): Shutdown ibus-bus connection. 522 // TODO(nona): Shutdown ibus-bus connection.
528 if (IBusConnectionsAreAlive()) { 523 if (IBusConnectionsAreAlive()) {
529 // Ask IBus to exit *asynchronously*. 524 // Ask IBus to exit *asynchronously*.
530 ibus_bus_exit_async(ibus_, 525 ibus_bus_exit_async(ibus_,
531 FALSE /* do not restart */, 526 FALSE /* do not restart */,
532 -1 /* timeout */, 527 -1 /* timeout */,
533 NULL /* cancellable */, 528 NULL /* cancellable */,
534 NULL /* callback */, 529 NULL /* callback */,
535 NULL /* user_data */); 530 NULL /* user_data */);
536 if (ibus_config_) {
537 // Release |ibus_config_| unconditionally to make sure next
538 // IBusConnectionsAreAlive() call will return false.
539 g_object_unref(ibus_config_);
540 ibus_config_ = NULL;
541 }
542 } else { 531 } else {
543 base::KillProcess(process_handle_, -1, false /* wait */); 532 base::KillProcess(process_handle_, -1, false /* wait */);
544 DVLOG(1) << "Killing ibus-daemon. PID=" 533 DVLOG(1) << "Killing ibus-daemon. PID="
545 << base::GetProcId(process_handle_); 534 << base::GetProcId(process_handle_);
546 } 535 }
547 process_handle_ = base::kNullProcessHandle; 536 process_handle_ = base::kNullProcessHandle;
548 return true; 537 return true;
549 } 538 }
550 539
551 bool IBusControllerImpl::ChangeInputMethod(const std::string& id) { 540 bool IBusControllerImpl::ChangeInputMethod(const std::string& id) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 IBusInputContextClient* client 607 IBusInputContextClient* client
619 = DBusThreadManager::Get()->GetIBusInputContextClient(); 608 = DBusThreadManager::Get()->GetIBusInputContextClient();
620 if (client) 609 if (client)
621 client->PropertyActivate(key, 610 client->PropertyActivate(key,
622 static_cast<ibus::IBusPropertyState>(is_radio)); 611 static_cast<ibus::IBusPropertyState>(is_radio));
623 return true; 612 return true;
624 } 613 }
625 614
626 bool IBusControllerImpl::IBusConnectionsAreAlive() { 615 bool IBusControllerImpl::IBusConnectionsAreAlive() {
627 return (ibus_daemon_status_ == IBUS_DAEMON_RUNNING) && 616 return (ibus_daemon_status_ == IBUS_DAEMON_RUNNING) &&
628 ibus_ && ibus_bus_is_connected(ibus_) && ibus_config_; 617 ibus_ && ibus_bus_is_connected(ibus_);
629 } 618 }
630 619
631 void IBusControllerImpl::MaybeRestoreConnections() { 620 void IBusControllerImpl::MaybeRestoreConnections() {
632 if (IBusConnectionsAreAlive()) 621 if (IBusConnectionsAreAlive())
633 return; 622 return;
634 MaybeRestoreIBusConfig();
635 if (IBusConnectionsAreAlive()) { 623 if (IBusConnectionsAreAlive()) {
636 DVLOG(1) << "ibus-daemon and ibus-memconf processes are ready."; 624 DVLOG(1) << "ibus-daemon and ibus-memconf processes are ready.";
637 ConnectPanelServiceSignals(); 625 ConnectPanelServiceSignals();
638 SendAllInputMethodConfigs();
639 if (!current_input_method_id_.empty()) 626 if (!current_input_method_id_.empty())
640 SendChangeInputMethodRequest(current_input_method_id_); 627 SendChangeInputMethodRequest(current_input_method_id_);
641 } 628 }
642 } 629 }
643 630
644 void IBusControllerImpl::MaybeInitializeIBusBus() { 631 void IBusControllerImpl::MaybeInitializeIBusBus() {
645 if (ibus_) 632 if (ibus_)
646 return; 633 return;
647 634
648 ibus_init(); 635 ibus_init();
649 // Establish IBus connection between ibus-daemon to change the current input 636 // Establish IBus connection between ibus-daemon to change the current input
650 // method engine, properties, and so on. 637 // method engine, properties, and so on.
651 ibus_ = ibus_bus_new(); 638 ibus_ = ibus_bus_new();
652 DCHECK(ibus_); 639 DCHECK(ibus_);
653 640
654 // Register callback functions for IBusBus signals. 641 // Register callback functions for IBusBus signals.
655 ConnectBusSignals(); 642 ConnectBusSignals();
656 643
657 // Ask libibus to watch the NameOwnerChanged signal *asynchronously*. 644 // Ask libibus to watch the NameOwnerChanged signal *asynchronously*.
658 ibus_bus_set_watch_dbus_signal(ibus_, TRUE); 645 ibus_bus_set_watch_dbus_signal(ibus_, TRUE);
659 646
660 if (ibus_bus_is_connected(ibus_)) { 647 if (ibus_bus_is_connected(ibus_)) {
661 DVLOG(1) << "IBus connection is ready: ibus-daemon is already running?"; 648 DVLOG(1) << "IBus connection is ready: ibus-daemon is already running?";
662 BusConnected(ibus_); 649 BusConnected(ibus_);
663 } 650 }
664 } 651 }
665 652
666 void IBusControllerImpl::MaybeRestoreIBusConfig() {
667 if (!ibus_)
668 return;
669
670 // Destroy the current |ibus_config_| object. No-op if it's NULL.
671 MaybeDestroyIBusConfig();
672
673 if (ibus_config_)
674 return;
675
676 GDBusConnection* ibus_connection = ibus_bus_get_connection(ibus_);
677 if (!ibus_connection) {
678 DVLOG(1) << "Couldn't create an ibus config object since "
679 << "IBus connection is not ready.";
680 return;
681 }
682
683 const gboolean disconnected
684 = g_dbus_connection_is_closed(ibus_connection);
685 if (disconnected) {
686 // |ibus_| object is not NULL, but the connection between ibus-daemon
687 // is not yet established. In this case, we don't create |ibus_config_|
688 // object.
689 DVLOG(1) << "Couldn't create an ibus config object since "
690 << "IBus connection is closed.";
691 return;
692 }
693 // If memconf is not successfully started yet, ibus_config_new() will
694 // return NULL. Otherwise, it returns a transfer-none and non-floating
695 // object. ibus_config_new() sometimes issues a D-Bus *synchronous* IPC
696 // to check if the org.freedesktop.IBus.Config service is available.
697 ibus_config_ = ibus_config_new(ibus_connection,
698 NULL /* do not cancel the operation */,
699 NULL /* do not get error information */);
700 if (!ibus_config_) {
701 DVLOG(1) << "ibus_config_new() failed. ibus-memconf is not ready?";
702 return;
703 }
704
705 // TODO(yusukes): g_object_weak_ref might be better since it allows
706 // libcros to detect the delivery of the "destroy" glib signal the
707 // |ibus_config_| object.
708 g_object_ref(ibus_config_);
709 DVLOG(1) << "ibus_config_ is ready.";
710 }
711
712 void IBusControllerImpl::MaybeDestroyIBusConfig() {
713 if (!ibus_) {
714 DVLOG(1) << "MaybeDestroyIBusConfig: ibus_ is NULL";
715 return;
716 }
717 if (ibus_config_ && !ibus_bus_is_connected(ibus_)) {
718 g_object_unref(ibus_config_);
719 ibus_config_ = NULL;
720 }
721 }
722
723 void IBusControllerImpl::SendChangeInputMethodRequest(const std::string& id) { 653 void IBusControllerImpl::SendChangeInputMethodRequest(const std::string& id) {
724 // Change the global engine *asynchronously*. 654 // Change the global engine *asynchronously*.
725 ibus_bus_set_global_engine_async(ibus_, 655 ibus_bus_set_global_engine_async(ibus_,
726 id.c_str(), 656 id.c_str(),
727 -1, // use the default ibus timeout 657 -1, // use the default ibus timeout
728 NULL, // cancellable 658 NULL, // cancellable
729 NULL, // callback 659 NULL, // callback
730 NULL); // user_data 660 NULL); // user_data
731 } 661 }
732 662
733 void IBusControllerImpl::SendAllInputMethodConfigs() {
734 DCHECK(IBusConnectionsAreAlive());
735
736 InputMethodConfigRequests::const_iterator iter =
737 current_config_values_.begin();
738 for (; iter != current_config_values_.end(); ++iter) {
739 SetInputMethodConfigInternal(iter->first, iter->second);
740 }
741 }
742
743 bool IBusControllerImpl::SetInputMethodConfigInternal( 663 bool IBusControllerImpl::SetInputMethodConfigInternal(
744 const ConfigKeyType& key, 664 const ConfigKeyType& key,
745 const InputMethodConfigValue& value) { 665 const InputMethodConfigValue& value) {
746 if (!IBusConnectionsAreAlive()) 666 IBusConfigClient* client = DBusThreadManager::Get()->GetIBusConfigClient();
747 return true; 667 if (!client)
668 return false;
748 669
749 // Convert the type of |value| from our structure to GVariant.
750 GVariant* variant = NULL;
751 switch (value.type) { 670 switch (value.type) {
752 case InputMethodConfigValue::kValueTypeString: 671 case InputMethodConfigValue::kValueTypeString:
753 variant = g_variant_new_string(value.string_value.c_str()); 672 client->SetStringValue(key.first,
754 break; 673 key.second,
674 value.string_value,
675 base::Bind(&ConfigSetValueErrorCallback));
676 return true;
755 case InputMethodConfigValue::kValueTypeInt: 677 case InputMethodConfigValue::kValueTypeInt:
756 variant = g_variant_new_int32(value.int_value); 678 client->SetIntValue(key.first,
757 break; 679 key.second,
680 value.int_value,
681 base::Bind(&ConfigSetValueErrorCallback));
682 return true;
758 case InputMethodConfigValue::kValueTypeBool: 683 case InputMethodConfigValue::kValueTypeBool:
759 variant = g_variant_new_boolean(value.bool_value); 684 client->SetBoolValue(key.first,
760 break; 685 key.second,
686 value.bool_value,
687 base::Bind(&ConfigSetValueErrorCallback));
688 return true;
761 case InputMethodConfigValue::kValueTypeStringList: 689 case InputMethodConfigValue::kValueTypeStringList:
762 GVariantBuilder variant_builder; 690 client->SetStringListValue(key.first,
763 g_variant_builder_init(&variant_builder, G_VARIANT_TYPE("as")); 691 key.second,
764 const size_t size = value.string_list_value.size(); 692 value.string_list_value,
765 // |size| could be 0 for some special configurations such as IBus hotkeys. 693 base::Bind(&ConfigSetValueErrorCallback));
766 for (size_t i = 0; i < size; ++i) { 694 return true;
767 g_variant_builder_add(&variant_builder, 695 default:
768 "s", 696 DVLOG(1) << "SendInputMethodConfig: unknown value.type";
769 value.string_list_value[i].c_str()); 697 return false;
770 }
771 variant = g_variant_builder_end(&variant_builder);
772 break;
773 } 698 }
774
775 if (!variant) {
776 DVLOG(1) << "SendInputMethodConfig: unknown value.type";
777 return false;
778 }
779 DCHECK(g_variant_is_floating(variant));
780 DCHECK(ibus_config_);
781
782 // Set an ibus configuration value *asynchronously*.
783 ibus_config_set_value_async(ibus_config_,
784 key.first.c_str(),
785 key.second.c_str(),
786 variant,
787 -1, // use the default ibus timeout
788 NULL, // cancellable
789 SetInputMethodConfigCallback,
790 g_object_ref(ibus_config_));
791
792 // Since |variant| is floating, ibus_config_set_value_async consumes
793 // (takes ownership of) the variable.
794 return true;
795 } 699 }
796 700
797 void IBusControllerImpl::ConnectBusSignals() { 701 void IBusControllerImpl::ConnectBusSignals() {
798 if (!ibus_) 702 if (!ibus_)
799 return; 703 return;
800 704
801 // We use g_signal_connect_after here since the callback should be called 705 // We use g_signal_connect_after here since the callback should be called
802 // *after* the IBusBusDisconnectedCallback in chromeos_input_method_ui.cc 706 // *after* the IBusBusDisconnectedCallback in chromeos_input_method_ui.cc
803 // is called. chromeos_input_method_ui.cc attaches the panel service object 707 // is called. chromeos_input_method_ui.cc attaches the panel service object
804 // to |ibus_|, and the callback in this file use the attached object. 708 // to |ibus_|, and the callback in this file use the attached object.
805 g_signal_connect_after(ibus_, 709 g_signal_connect_after(ibus_,
806 "connected", 710 "connected",
807 G_CALLBACK(BusConnectedThunk), 711 G_CALLBACK(BusConnectedThunk),
808 this); 712 this);
809
810 g_signal_connect(ibus_,
811 "disconnected",
812 G_CALLBACK(BusDisconnectedThunk),
813 this);
814
815 g_signal_connect(ibus_,
816 "name-owner-changed",
817 G_CALLBACK(BusNameOwnerChangedThunk),
818 this);
819 } 713 }
820 714
821 void IBusControllerImpl::ConnectPanelServiceSignals() { 715 void IBusControllerImpl::ConnectPanelServiceSignals() {
822 if (!ibus_) 716 if (!ibus_)
823 return; 717 return;
824 718
825 IBusPanelService* ibus_panel_service = IBUS_PANEL_SERVICE( 719 IBusPanelService* ibus_panel_service = IBUS_PANEL_SERVICE(
826 g_object_get_data(G_OBJECT(ibus_), kPanelObjectKey)); 720 g_object_get_data(G_OBJECT(ibus_), kPanelObjectKey));
827 if (!ibus_panel_service) { 721 if (!ibus_panel_service) {
828 DVLOG(1) << "IBusPanelService is NOT available."; 722 DVLOG(1) << "IBusPanelService is NOT available.";
829 return; 723 return;
830 } 724 }
831 // We don't _ref() or _weak_ref() the panel service object, since we're not 725 // We don't _ref() or _weak_ref() the panel service object, since we're not
832 // interested in the life time of the object. 726 // interested in the life time of the object.
833 g_signal_connect(ibus_panel_service, 727 g_signal_connect(ibus_panel_service,
834 "register-properties", 728 "register-properties",
835 G_CALLBACK(RegisterPropertiesThunk), 729 G_CALLBACK(RegisterPropertiesThunk),
836 this); 730 this);
837 g_signal_connect(ibus_panel_service, 731 g_signal_connect(ibus_panel_service,
838 "update-property", 732 "update-property",
839 G_CALLBACK(UpdatePropertyThunk), 733 G_CALLBACK(UpdatePropertyThunk),
840 this); 734 this);
841 } 735 }
842 736
843 void IBusControllerImpl::BusConnected(IBusBus* bus) { 737 void IBusControllerImpl::BusConnected(IBusBus* bus) {
844 DVLOG(1) << "IBus connection is established."; 738 DVLOG(1) << "IBus connection is established.";
845 MaybeRestoreConnections(); 739 MaybeRestoreConnections();
846 } 740 }
847 741
848 void IBusControllerImpl::BusDisconnected(IBusBus* bus) {
849 DVLOG(1) << "IBus connection is terminated.";
850 // ibus-daemon might be terminated. Since |ibus_| object will automatically
851 // connect to the daemon if it restarts, we don't have to set NULL on ibus_.
852 // Call MaybeDestroyIBusConfig() to set |ibus_config_| to NULL temporarily.
853 MaybeDestroyIBusConfig();
854 }
855
856 void IBusControllerImpl::BusNameOwnerChanged(IBusBus* bus,
857 const gchar* name,
858 const gchar* old_name,
859 const gchar* new_name) {
860 DCHECK(name);
861 DCHECK(old_name);
862 DCHECK(new_name);
863
864 if (name != std::string("org.freedesktop.IBus.Config")) {
865 // Not a signal for ibus-memconf.
866 return;
867 }
868
869 const std::string empty_string;
870 if (old_name != empty_string || new_name == empty_string) {
871 // ibus-memconf died?
872 DVLOG(1) << "Unexpected name owner change: name=" << name
873 << ", old_name=" << old_name << ", new_name=" << new_name;
874 // TODO(yusukes): it might be nice to set |ibus_config_| to NULL and call
875 // a new callback function like OnDisconnect() here to allow Chrome to
876 // recover all input method configurations when ibus-memconf is
877 // automatically restarted by ibus-daemon. Though ibus-memconf is pretty
878 // stable and unlikely crashes.
879 return;
880 }
881 DVLOG(1) << "IBus config daemon is started. Recovering ibus_config_";
882
883 // Try to recover |ibus_config_|. If the |ibus_config_| object is
884 // successfully created, |OnConnectionChange| will be called to
885 // notify Chrome that IBus is ready.
886 MaybeRestoreConnections();
887 }
888
889 void IBusControllerImpl::RegisterProperties(IBusPanelService* panel, 742 void IBusControllerImpl::RegisterProperties(IBusPanelService* panel,
890 IBusPropList* ibus_prop_list) { 743 IBusPropList* ibus_prop_list) {
891 // Note: |panel| can be NULL. See ChangeInputMethod(). 744 // Note: |panel| can be NULL. See ChangeInputMethod().
892 DVLOG(1) << "RegisterProperties" << (ibus_prop_list ? "" : " (clear)"); 745 DVLOG(1) << "RegisterProperties" << (ibus_prop_list ? "" : " (clear)");
893 746
894 current_property_list_.clear(); 747 current_property_list_.clear();
895 if (ibus_prop_list) { 748 if (ibus_prop_list) {
896 // You can call 749 // You can call
897 // DVLOG(1) << "\n" << PrintPropList(ibus_prop_list, 0); 750 // DVLOG(1) << "\n" << PrintPropList(ibus_prop_list, 0);
898 // here to dump |ibus_prop_list|. 751 // here to dump |ibus_prop_list|.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 static_cast<ui::InputMethodIBus*>( 855 static_cast<ui::InputMethodIBus*>(
1003 ash::Shell::GetPrimaryRootWindow()->GetProperty( 856 ash::Shell::GetPrimaryRootWindow()->GetProperty(
1004 aura::client::kRootWindowInputMethodKey)); 857 aura::client::kRootWindowInputMethodKey));
1005 } 858 }
1006 859
1007 void IBusControllerImpl::set_input_method_for_testing( 860 void IBusControllerImpl::set_input_method_for_testing(
1008 ui::InputMethodIBus* input_method) { 861 ui::InputMethodIBus* input_method) {
1009 input_method_ = input_method; 862 input_method_ = input_method;
1010 } 863 }
1011 864
865 void IBusControllerImpl::OnIBusConfigClientInitialized() {
866 InputMethodConfigRequests::const_iterator iter =
867 current_config_values_.begin();
868 for (; iter != current_config_values_.end(); ++iter) {
869 SetInputMethodConfigInternal(iter->first, iter->second);
870 }
871 }
872
1012 // static 873 // static
1013 void IBusControllerImpl::IBusDaemonInitializationDone( 874 void IBusControllerImpl::IBusDaemonInitializationDone(
1014 IBusControllerImpl* controller, 875 IBusControllerImpl* controller,
1015 const std::string& ibus_address) { 876 const std::string& ibus_address) {
1016 if (controller->ibus_daemon_address_ != ibus_address) 877 if (controller->ibus_daemon_address_ != ibus_address)
1017 return; 878 return;
1018 879
1019 if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { 880 if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) {
1020 // Stop() or OnIBusDaemonExit() has already been called. 881 // Stop() or OnIBusDaemonExit() has already been called.
1021 return; 882 return;
1022 } 883 }
1023 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address); 884 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address);
1024 controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING; 885 controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING;
1025 886
1026 ui::InputMethodIBus* input_method_ibus = controller->GetInputMethod(); 887 ui::InputMethodIBus* input_method_ibus = controller->GetInputMethod();
1027 DCHECK(input_method_ibus); 888 DCHECK(input_method_ibus);
1028 input_method_ibus->OnConnected(); 889 input_method_ibus->OnConnected();
1029 890
891 DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync(
892 base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized,
893 controller->weak_ptr_factory_.GetWeakPtr()));
894
1030 FOR_EACH_OBSERVER(Observer, controller->observers_, OnConnected()); 895 FOR_EACH_OBSERVER(Observer, controller->observers_, OnConnected());
1031 896
1032 VLOG(1) << "The ibus-daemon initialization is done."; 897 VLOG(1) << "The ibus-daemon initialization is done.";
1033 } 898 }
1034 899
1035 // static 900 // static
1036 void IBusControllerImpl::SetInputMethodConfigCallback(GObject* source_object,
1037 GAsyncResult* res,
1038 gpointer user_data) {
1039 IBusConfig* config = IBUS_CONFIG(user_data);
1040 g_return_if_fail(config);
1041
1042 GError* error = NULL;
1043 const gboolean result =
1044 ibus_config_set_value_async_finish(config, res, &error);
1045
1046 if (!result) {
1047 std::string message = "(unknown error)";
1048 if (error && error->message) {
1049 message = error->message;
1050 }
1051 DVLOG(1) << "ibus_config_set_value_async failed: " << message;
1052 }
1053
1054 if (error)
1055 g_error_free(error);
1056 g_object_unref(config);
1057 }
1058
1059 // static
1060 void IBusControllerImpl::OnIBusDaemonExit(GPid pid, 901 void IBusControllerImpl::OnIBusDaemonExit(GPid pid,
1061 gint status, 902 gint status,
1062 IBusControllerImpl* controller) { 903 IBusControllerImpl* controller) {
1063 if (controller->process_handle_ != base::kNullProcessHandle) { 904 if (controller->process_handle_ != base::kNullProcessHandle) {
1064 if (base::GetProcId(controller->process_handle_) == pid) { 905 if (base::GetProcId(controller->process_handle_) == pid) {
1065 // ibus-daemon crashed. 906 // ibus-daemon crashed.
1066 // TODO(nona): Shutdown ibus-bus connection. 907 // TODO(nona): Shutdown ibus-bus connection.
1067 controller->process_handle_ = base::kNullProcessHandle; 908 controller->process_handle_ = base::kNullProcessHandle;
1068 } else { 909 } else {
1069 // This condition is as follows. 910 // This condition is as follows.
(...skipping 26 matching lines...) Expand all
1096 937
1097 // static 938 // static
1098 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( 939 bool IBusControllerImpl::FindAndUpdatePropertyForTesting(
1099 const chromeos::input_method::InputMethodProperty& new_prop, 940 const chromeos::input_method::InputMethodProperty& new_prop,
1100 chromeos::input_method::InputMethodPropertyList* prop_list) { 941 chromeos::input_method::InputMethodPropertyList* prop_list) {
1101 return FindAndUpdateProperty(new_prop, prop_list); 942 return FindAndUpdateProperty(new_prop, prop_list);
1102 } 943 }
1103 944
1104 } // namespace input_method 945 } // namespace input_method
1105 } // namespace chromeos 946 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/input_method/ibus_controller_impl.h ('k') | chromeos/dbus/dbus_thread_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698