| Index: chromeos/dbus/ibus/ibus_config_client.cc
|
| diff --git a/chromeos/dbus/ibus/ibus_config_client.cc b/chromeos/dbus/ibus/ibus_config_client.cc
|
| index 659cde41bae779420cb748a81ec0c4286f16c0e9..8be2e09e388110c668c5fb8a615a87d68d5d4d2c 100644
|
| --- a/chromeos/dbus/ibus/ibus_config_client.cc
|
| +++ b/chromeos/dbus/ibus/ibus_config_client.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chromeos/dbus/ibus/ibus_config_client.h"
|
|
|
| +#include <vector>
|
| +
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| #include "chromeos/dbus/ibus/ibus_constants.h"
|
| @@ -17,23 +19,69 @@ namespace chromeos {
|
|
|
| namespace {
|
|
|
| +// Called when the |signal| is connected.
|
| +void OnSignalConnected(const std::string& interface,
|
| + const std::string& signal,
|
| + bool succeeded) {
|
| + LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " "
|
| + << signal << " failed.";
|
| +}
|
| +
|
| +// Called when the GetNameOwner method call is failed.
|
| +void OnGetNameOwnerFail(dbus::ErrorResponse* response) {
|
| + // Do nothing, because method call sometimes fails due to bootstrap timing of
|
| + // ibus-memconf.
|
| +}
|
| +
|
| // The IBusConfigClient implementation.
|
| class IBusConfigClientImpl : public IBusConfigClient {
|
| public:
|
| explicit IBusConfigClientImpl(dbus::Bus* bus)
|
| - : proxy_(bus->GetObjectProxy(ibus::kServiceName,
|
| - dbus::ObjectPath(
|
| - ibus::config::kServicePath))),
|
| + : proxy_(NULL),
|
| + bus_(bus),
|
| weak_ptr_factory_(this) {
|
| }
|
|
|
| virtual ~IBusConfigClientImpl() {}
|
|
|
| // IBusConfigClient override.
|
| + virtual void InitializeAsync(const OnIBusConfigReady& on_ready) OVERRIDE {
|
| + // We should check that the ibus-config daemon actually works first, so we
|
| + // can't initialize synchronously.
|
| + dbus::ObjectProxy* dbus_proxy = bus_->GetObjectProxy(
|
| + ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath));
|
| +
|
| + // Watch NameOwnerChanged signal which is fired when the ibus-config daemon
|
| + // request its name ownership.
|
| + dbus_proxy->ConnectToSignal(
|
| + ibus::kDBusInterface,
|
| + ibus::kNameOwnerChangedSignal,
|
| + base::Bind(&IBusConfigClientImpl::OnNameOwnerChanged,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + on_ready),
|
| + base::Bind(&OnSignalConnected));
|
| +
|
| + dbus::MethodCall method_call(ibus::kDBusInterface,
|
| + ibus::kGetNameOwnerMethod);
|
| + dbus::MessageWriter writer(&method_call);
|
| + writer.AppendString(ibus::config::kServiceName);
|
| + dbus_proxy->CallMethodWithErrorCallback(
|
| + &method_call,
|
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&IBusConfigClientImpl::OnGetNameOwner,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + on_ready),
|
| + base::Bind(&OnGetNameOwnerFail));
|
| + }
|
| +
|
| + // IBusConfigClient override.
|
| virtual void SetStringValue(const std::string& section,
|
| const std::string& key,
|
| const std::string& value,
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| + if (!proxy_)
|
| + return;
|
| DCHECK(!error_callback.is_null());
|
| dbus::MethodCall method_call(ibus::config::kServiceInterface,
|
| ibus::config::kSetValueMethod);
|
| @@ -52,6 +100,8 @@ class IBusConfigClientImpl : public IBusConfigClient {
|
| const std::string& key,
|
| int value,
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| + if (!proxy_)
|
| + return;
|
| DCHECK(!error_callback.is_null());
|
| dbus::MethodCall method_call(ibus::config::kServiceInterface,
|
| ibus::config::kSetValueMethod);
|
| @@ -70,6 +120,8 @@ class IBusConfigClientImpl : public IBusConfigClient {
|
| const std::string& key,
|
| bool value,
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| + if (!proxy_)
|
| + return;
|
| DCHECK(!error_callback.is_null());
|
| dbus::MethodCall method_call(ibus::config::kServiceInterface,
|
| ibus::config::kSetValueMethod);
|
| @@ -89,6 +141,8 @@ class IBusConfigClientImpl : public IBusConfigClient {
|
| const std::string& key,
|
| const std::vector<std::string>& value,
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| + if (!proxy_)
|
| + return;
|
| DCHECK(!error_callback.is_null());
|
| dbus::MethodCall method_call(ibus::config::kServiceInterface,
|
| ibus::config::kSetValueMethod);
|
| @@ -111,6 +165,8 @@ class IBusConfigClientImpl : public IBusConfigClient {
|
| private:
|
| void CallWithDefaultCallback(dbus::MethodCall* method_call,
|
| const ErrorCallback& error_callback) {
|
| + if (!proxy_)
|
| + return;
|
| proxy_->CallMethodWithErrorCallback(
|
| method_call,
|
| dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| @@ -136,7 +192,72 @@ class IBusConfigClientImpl : public IBusConfigClient {
|
| error_callback.Run();
|
| }
|
|
|
| + void OnNameOwnerChanged(const OnIBusConfigReady& on_ready,
|
| + dbus::Signal* signal) {
|
| + DCHECK(signal);
|
| + std::string name;
|
| + std::string old_owner;
|
| + std::string new_owner;
|
| +
|
| + dbus::MessageReader reader(signal);
|
| + if (!reader.PopString(&name) ||
|
| + !reader.PopString(&old_owner) ||
|
| + !reader.PopString(&new_owner)) {
|
| + DLOG(ERROR) << "Invalid response of NameOwnerChanged."
|
| + << signal->ToString();
|
| + return;
|
| + }
|
| +
|
| + if (name != ibus::config::kServiceName)
|
| + return; // Not a signal for ibus-config.
|
| +
|
| + if (!old_owner.empty() || new_owner.empty()) {
|
| + DVLOG(1) << "Unexpected name owner change: name=" << name
|
| + << ", old_owner=" << old_owner << ", new_owner=" << new_owner;
|
| + proxy_ = NULL;
|
| + return;
|
| + }
|
| +
|
| + if (proxy_)
|
| + return; // Already initialized.
|
| +
|
| + proxy_ = bus_->GetObjectProxy(ibus::config::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath));
|
| + if (!on_ready.is_null())
|
| + on_ready.Run();
|
| + }
|
| +
|
| + // Handles response of GetNameOwner.
|
| + void OnGetNameOwner(const OnIBusConfigReady& on_ready,
|
| + dbus::Response* response) {
|
| + if (!response) {
|
| + LOG(ERROR) << "Response is NULL.";
|
| + return;
|
| + }
|
| + std::string owner;
|
| + dbus::MessageReader reader(response);
|
| +
|
| + if (!reader.PopString(&owner)) {
|
| + LOG(ERROR) << "Invalid response of GetNameOwner."
|
| + << response->ToString();
|
| + return;
|
| + }
|
| +
|
| + // If the owner is empty, ibus-config daemon is not ready. So will
|
| + // initialize object proxy on NameOwnerChanged signal.
|
| + if (owner.empty())
|
| + return;
|
| +
|
| + proxy_ = bus_->GetObjectProxy(ibus::config::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath));
|
| + if (!on_ready.is_null())
|
| + on_ready.Run();
|
| + }
|
| +
|
| dbus::ObjectProxy* proxy_;
|
| + dbus::Bus* bus_;
|
| base::WeakPtrFactory<IBusConfigClientImpl> weak_ptr_factory_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(IBusConfigClientImpl);
|
| @@ -147,6 +268,7 @@ class IBusConfigClientStubImpl : public IBusConfigClient {
|
| public:
|
| IBusConfigClientStubImpl() {}
|
| virtual ~IBusConfigClientStubImpl() {}
|
| + virtual void InitializeAsync(const OnIBusConfigReady& on_ready) OVERRIDE {}
|
| virtual void SetStringValue(const std::string& section,
|
| const std::string& key,
|
| const std::string& value,
|
|
|